关于泛型和静态组合的有关问题

关于泛型和静态组合的问题
我们知道,如果要在一个类中使用泛型,可以在类声明的地方对泛型进行声明,完后在整个类中都可以使用该泛型了,但对于这个,我还有一点疑问,看下面的一个例子


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(如果不是静态方法,我试过不需要),我在类的最开始明明声明过了
------解决思路----------------------
引用:
Quote: 引用:

Quote: 引用:

Quote: 引用:

定义静态方法static keyword 后面必须跟着泛型标识<T>


现在验证结果是这样,我也写出来了,我想知道的是为什么


因为java语言就是这么要求的,不这么做就不给编译.这就是规定


Java原话是什么,找出来看看,肯定有说明原因



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之类的包里,就应该这么写的。