[java] почему нельзя создавать static-методы в генериках?

psihodog

На такое:
class Templ <T> {
public static T h(T t) {return t;}
}
ругается:
test.java:12: non-static class T cannot be referenced from a static context
public static T h(T t) {return t;}
^
test.java:12: non-static class T cannot be referenced from a static context
public static T h(T t) {return t;}
^
2 errors

в то время как:
	public static <T> T g(T t) {return t;}
всё ок.

livemix

Попробую ответить.
Во втором случае параметризован сам метод класса. Причем это T никак не связано с тем T, которое находится
сlass Templ<T>  
. В момент вызова метода ему передается конкретный тип.
В первом случае конкретный тип T становится известен только после создания объекта, например, после такого
Templ<Object> = new Templ<Object>  
а статический метод может быть вызван без создания объекта.

Dasar

С другой стороны - при следующей записи:

Temp<int>.h(1);
тип шаблона же становится ясен.

psihodog

Во втором случае параметризован сам метод класса. Причем это T никак не связано с тем T, которое находится в сlass Templ<T>
ну да, g у меня вообще из другого класса.
В момент вызова метода ему передается конкретный тип.
В жаве для генериков от разных типов используется один и тот же рантайм код. А это значит, что вся реальная работа по обработке типа данного в параметр генерику происходит на момент компиляции. В частности, в момент вызова никакой тип методу не передаётся.
В первом случае конкретный тип T становится известен только после создания объекта
Не создания, а объявления, я думаю.

psihodog

да, только компилер выдаёт ошибку.

Dasar

Имхо, Java-разработчики что-то не доделали, потому что в .Net-е такая фишка работает.

psihodog

Да просто не понятно, почему такое ограничение может быть. Но по любому в спецификации Жавы оно прописано!
The Java™ Language Specification Third Edition:
It is a compile-time error to refer to a type parameter of a class C anywhere in
the declaration of a static member of C or the declaration of a static member of
any type declaration nested within C. It is a compile-time error to refer to a type
parameter of a class C within a static initializer of C or any class nested within C.

psihodog

Java in a Nutshell, 5th Edition:
Notice that the type variables declared by a generic type can be used only by the instance fields and methods (and nested types) of the type and not by static fields and methods. The reason, of course, is that it is instances of generic types that are parameterized. Static members are shared by all instances and parameterizations of the class, so static members do not have type parameters associated with them. Methods, including static methods, can declare and use their own type parameters, however, and each invocation of such a method can be parameterized differently.
Оставить комментарий
Имя или ник:
Комментарий: