Java泛型和静态工厂方法——语法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20751867/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Generics and Static Factory Methods -- Syntax
提问by FateNuller
Here's what I've got:
这是我所拥有的:
public class Node<T> {
// instance variables
private Node<T> next;
private T data;
// construct with data
private Node(T data){
next = null;
this.data = data;
}
// construct without data
private Node(){
next = null;
this.data = null;
}
// static factory method
public static <T> Node<T> newNodeWithData(T data){
return new Node<T>(data);
}
// static factory method
public static <T> Node<T> newNode(){
return new Node<T>();
}
...
}
My question really just about the syntax of generics coupled with that of a static factory method. I don't really understand whywe put the < T > before the return type in the method declaration. Is it kind of like typecasting? Any help would be much appreciated!
我的问题实际上只是关于泛型的语法与静态工厂方法的语法相结合。我真的不明白为什么我们将 < T > 放在方法声明中的返回类型之前。这有点像类型转换?任何帮助将非常感激!
采纳答案by Brian Roach
What you're asking about is type inferrence.
您要问的是类型推断。
Since it's a static method it has to infer the Generic type from somewhere; You don't have an instance of the class. That's what the <T>
means.
由于它是一个静态方法,它必须从某个地方推断出 Generic 类型;您没有该类的实例。就是这个<T>
意思。
In the case of your method that takes no arguments it's actually inferring it from the target of the assignment. For example, say your method looked like this:
对于不带参数的方法,它实际上是从赋值的目标中推断出来的。例如,假设您的方法如下所示:
public static <T> List<T> getNewList() {
return new ArrayList<T>();
}
When using this method, T
is inferred from the target (in this case String
):
使用此方法时,T
从目标推断(在本例中String
):
List<String> myList = MyClass.getNewList();
In your other static method where you have a Generic argument, T
is being inferred from the type being passed in:
在您具有 Generic 参数的其他静态方法中,T
是从传入的类型推断出来的:
public static <T> List<T> getNewListWithElement(T element) {
List<T> list = new ArrayList<T>();
list.add(element);
return list;
}
Here, if you tried doing:
在这里,如果您尝试执行以下操作:
List<String> myList = MyClass.getNewListWithElement(new Integer(4));
It would tell you that your target type was wrong, and you needed a List<Integer>
它会告诉你你的目标类型是错误的,你需要一个 List<Integer>
Specifically this is covered in sections 15.12.2.7and 15.12.2.8of the JLS.
回答by Sibbo
The <T>
is just the signal, that this method uses T
as type variable. Without it, the compiler would think, T
is a class
, interface
or enum
that is declared somewhere and output an error. It is not the same T
as used in your first line. You can replace the T
in this method with any other letter, maybe that helps understanding.
这<T>
只是此方法T
用作类型变量的信号。没有它,编译器会认为T
是 a class
,interface
或者enum
在某处声明并输出错误。它与T
第一行中使用的不同。您可以T
用任何其他字母替换此方法中的,这可能有助于理解。
回答by Andrey Chaschev
This is an only way to parametrize a static method, as the original T
in the Node declaration is bound to instance fields and methods of the Node. So you could write:
这是参数化静态方法的唯一方法,因为T
Node 声明中的原始方法绑定到 Node.js 的实例字段和方法。所以你可以写:
public static <T1> Node<T1> newNode(){
return new Node<T1>();
}
The original T
is bound to an instance of Node
class and cannot be referenced in static context. This would result in a compilation error:
原件T
绑定到Node
类的实例,不能在静态上下文中引用。这将导致编译错误:
// ERROR
public static Node<T> newNode(){
return new Node<T>();
}
回答by OldCurmudgeon
The reason you must decorate the static method with such sugar is because, as a static method, it does not inherit the T
from the declaration of the class.
必须用这样的糖装饰静态方法的原因是,作为静态方法,它不会T
从类的声明中继承。
You could just as well do:
你也可以这样做:
// static factory methods
public static <Q> Node<Q> newNode(){
return new Node<Q>();
}
public static Node<String> newStringNode(String s){
return new Node<String>(s);
}
A simple narrative to the declaration may assist:
声明的简单叙述可能有助于:
// This static method would have a <T> parameter to the class if it was not static
public static <T>
// It returns an object of type `Node` with generic parameter T
Node<T> newNode(){
// And here it is doing it's business.
return new Node<T>();
}
回答by danidacar
T inferred from parameter
从参数推断的 T
public static <T> List<T> getNewListWithElement(T element)
How can the compiler make the difference between T as a class and T as a generic argument? The solution is to use to specify T element is a generic and not a class/interface.
编译器如何区分 T 作为类和 T 作为泛型参数?解决方案是使用指定 T 元素是泛型而不是类/接口。
T inferred from usage
从用法推断的 T
public static <T1> Node<T1> newNode(){
return new Node<T1>();
}
Who will be T1 inside the method body if no declaration would be made?
如果不进行声明,谁将成为方法主体内的 T1?