关于泛型和静态组合的有关问题
关于泛型和静态组合的问题
我们知道,如果要在一个类中使用泛型,可以在类声明的地方对泛型进行声明,完后在整个类中都可以使用该泛型了,但对于这个,我还有一点疑问,看下面的一个例子
现在奇怪的地方在于这个
如果不在my<T>前面写<T>,会报错,意思是静态方法里不能用非静态变量T,但如果我将T写成String,也就是下面的
却不报这个错了,我不明白为什么会这样,为什么返回值为泛型的静态方法,需要再次声明T(如果不是静态方法,我试过不需要),我在类的最开始明明声明过了
------解决思路----------------------
JAVA 文档
The syntax for a generic method includes a type parameter, inside angle brackets, and appears before the method's return type. For static generic methods, the type parameter section must appear before the method's return type.
------解决思路----------------------
这其实不难理解,把T想象成my的一个成员,因为T是实例依赖的,显然不同的实例T可以不一样;那么为啥静态方法引用一个可以改变的T就不行呢?擦除机制决定了泛型只存在于编译期,实际上编译生成的类文件中并不存在T的上下文,所以必须是死的。
而且,静态泛型方法前边的T也并不是泛型类的T。看代码:
T改成S照样用不耽误。
其实这种混杂工厂模式的泛型广泛存在于guava之类的包里,就应该这么写的。
我们知道,如果要在一个类中使用泛型,可以在类声明的地方对泛型进行声明,完后在整个类中都可以使用该泛型了,但对于这个,我还有一点疑问,看下面的一个例子
public class Test {
public static void main(String[] args) throws Exception {
}
}
class my<T> {
T result;
public static <T> my<T> getThis(T result) {
return new my(result);
}
public static my<String> getThis2(String result) {
return new my(result);
}
private my(T result) {
this.result = result;
}
private my(String str) {
}
}
现在奇怪的地方在于这个
public static <T> my<T> getThis(T result) {
return new my(result);
}
如果不在my<T>前面写<T>,会报错,意思是静态方法里不能用非静态变量T,但如果我将T写成String,也就是下面的
public static my<String> getThis2(String result) {
return new my(result);
}
却不报这个错了,我不明白为什么会这样,为什么返回值为泛型的静态方法,需要再次声明T(如果不是静态方法,我试过不需要),我在类的最开始明明声明过了
------解决思路----------------------
JAVA 文档
The syntax for a generic method includes a type parameter, inside angle brackets, and appears before the method's return type. For static generic methods, the type parameter section must appear before the method's return type.
------解决思路----------------------
这其实不难理解,把T想象成my的一个成员,因为T是实例依赖的,显然不同的实例T可以不一样;那么为啥静态方法引用一个可以改变的T就不行呢?擦除机制决定了泛型只存在于编译期,实际上编译生成的类文件中并不存在T的上下文,所以必须是死的。
而且,静态泛型方法前边的T也并不是泛型类的T。看代码:
public class Test {
public static void main(String[] args) throws Exception {
my<Integer> m = my.getThis(5);
System.out.println(m.result.getClass());
}
}
class my<S> {
S result;
public static <T> my<T> getThis(T result) {
return new my<T>(result);
}
public static my<String> getThis2(String result) {
return new my(result);
}
private my(S result) {
this.result = result;
}
private my(String str) {
}
}
T改成S照样用不耽误。
其实这种混杂工厂模式的泛型广泛存在于guava之类的包里,就应该这么写的。