[英]Why can't I explicitly pass the type argument to a generic Java method?
I have defined a Java function:我定义了一个 Java 函数:
static <T> List<T> createEmptyList() {
return new ArrayList<T>();
}
One way to call it is like so:调用它的一种方法是这样的:
List<Integer> myList = createEmptyList(); // Compiles
Why can't I call it by explicitly passing the generic type argument?为什么我不能通过显式传递泛型类型参数来调用它? : :
Object myObject = createEmtpyList<Integer>(); // Doesn't compile. Why?
I get the error Illegal start of expression
from the compiler.我从编译器收到错误Illegal start of expression
。
When the java compiler cannot infer the parameter type by itself for a static method, you can always pass it using the full qualified method name: Class . 当java编译器无法为静态方法自己推断参数类型时,您始终可以使用完全限定的方法名称传递它:Class。 < Type > method(); <Type> method();
Object list = Collections.<String> emptyList();
You can, if you pass in the type as a method parameter. 如果将类型作为方法参数传入,则可以。
static <T> List<T> createEmptyList( Class<T> type ) {
return new ArrayList<T>();
}
@Test
public void createStringList() {
List<String> stringList = createEmptyList( String.class );
}
Methods cannot be genericised in the same way that a type can, so the only option for a method with a dynamically-typed generic return type -- phew that's a mouthful :-) -- is to pass in the type as an argument. 方法不能以与类型相同的方式进行泛化,因此具有动态类型泛型返回类型的方法的唯一选项 - phew是满口的:-) - 是将类型作为参数传递。
For a truly excellent FAQ on Java generics, see Angelika Langer's generics FAQ . 有关Java泛型的真正优秀常见问题, 请参阅Angelika Langer的泛型常见问题解答 。
. 。
. 。
Follow-up: 跟进:
It wouldn't make sense in this context to use the array argument as in Collection.toArray( T[] )
. 在此上下文中使用Collection.toArray( T[] )
的数组参数是没有意义的。 The only reason an array is used there is because the same (pre-allocated) array is used to contain the results (if the array is large enough to fit them all in). 在那里使用数组的唯一原因是因为使用相同的(预分配的)数组来包含结果(如果数组足够大以使它们全部适合)。 This saves on allocating a new array at run-time all the time. 这节省了在运行时始终分配新阵列的过程。
However, for the purposes of education, if you did want to use the array typing, the syntax is very similar: 但是,出于教育目的,如果您确实想要使用数组类型,则语法非常相似:
static <T> List<T> createEmptyList( T[] array ) {
return new ArrayList<T>();
}
@Test
public void testThing() {
List<Integer> integerList = createEmptyList( new Integer[ 1 ] );
}
It was quite some time since I dug into those parts of Java, but... 自从我挖掘Java的那些部分以来已经有一段时间了,但......
Why you can't do it was probably a design choice by the language developers. 为什么你不能这样做可能是语言开发人员的设计选择。 Still, due to the type erasure employed by Java, the generics information gets dropped at compile time anyway, so in your example it would create exactly the same byte code whether you had the type parameter or not. 尽管如此,由于Java使用的类型擦除 ,泛型信息无论如何都会在编译时被删除,因此在您的示例中,无论您是否具有类型参数,它都将创建完全相同的字节代码。
@pauldoo Yes, you are quite right. @pauldoo是的,你是对的。 It is one of the weaknesses with the java generics imho. 这是java泛型imho的弱点之一。
I response to Cheekysoft I'd like to propose to also look at how it is done by the Java people themselves, such as T[] AbstractCollection#toArray (T[] a). 我对Cheekysoft的回应我想建议看一下Java人员自己如何做,比如T [] AbstractCollection#toArray (T [] a)。 I think Cheekysofts version is superior, but the Java one has the advantage of familiarity. 我认为Cheekysofts版本更优越,但Java版本具有熟悉的优势。
Edit: Added link. 编辑:添加链接。 Re-edit: Found a bug on SO :) 重新编辑:在SO上发现了一个bug :)
Follow-up on Cheekysoft: Well, as it is a list of some type that should be returned the corresponding example should look something like: 关于Cheekysoft的后续行动:嗯,因为它是应该返回的某种类型的列表,相应的示例应该类似于:
static <T> List<T> createEmptyList( List<T> a ) {
return new ArrayList<T>();
}
But yes, passing the class object is clearly the better one. 但是,传递类对象显然是更好的。 My only argument is that of familiarity, and in this exact instance it isn't worth much (in fact it is bad). 我唯一的论点就是熟悉,而在这个确切的例子中它并不值得(事实上它很糟糕)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.