我定义了一个 Java 函数:

static <T> List<T> createEmptyList() {
    return new ArrayList<T>();
}

调用它的一种方法是这样的:

List<Integer> myList = createEmptyList(); // Compiles

为什么我不能通过显式传递泛型类型参数来调用它?

Object myObject = createEmtpyList<Integer>(); // Doesn't compile. Why?

我从编译器收到错误Illegal start of expression

#1楼 票数:35 已采纳

当java编译器无法为静态方法自己推断参数类型时,您始终可以使用完全限定的方法名称传递它:Class。 <Type> method();

Object list = Collections.<String> emptyList();

#2楼 票数:24

如果将类型作为方法参数传入,则可以。

static <T> List<T> createEmptyList( Class<T> type ) {
  return new ArrayList<T>();
}

@Test
public void createStringList() {
  List<String> stringList = createEmptyList( String.class );
}

方法不能以与类型相同的方式进行泛化,因此具有动态类型泛型返回类型的方法的唯一选项 - phew是满口的:-) - 是将类型作为参数传递。

有关Java泛型的真正优秀常见问题, 请参阅Angelika Langer的泛型常见问题解答


跟进:

在此上下文中使用Collection.toArray( T[] )的数组参数是没有意义的。 在那里使用数组的唯一原因是因为使用相同的(预分配的)数组来包含结果(如果数组足够大以使它们全部适合)。 这节省了在运行时始终分配新阵列的过程。

但是,出于教育目的,如果您确实想要使用数组类型,则语法非常相似:

static <T> List<T> createEmptyList( T[] array ) {
  return new ArrayList<T>();
}

@Test
public void testThing() {
  List<Integer> integerList = createEmptyList( new Integer[ 1 ] );
}

#3楼 票数:1

自从我挖掘Java的那些部分以来已经有一段时间了,但......

为什么你不能这样做可能是语言开发人员的设计选择。 尽管如此,由于Java使用的类型擦除 ,泛型信息无论如何都会在编译时被删除,因此在您的示例中,无论您是否具有类型参数,它都将创建完全相同的字节代码。

#4楼 票数:0

@pauldoo是的,你是对的。 这是java泛型imho的弱点之一。

我对Cheekysoft的回应我想建议看一下Java人员自己如何做,比如T [] AbstractCollection#toArray (T [] a)。 我认为Cheekysofts版本更优越,但Java版本具有熟悉的优势。

编辑:添加链接。 重新编辑:在SO上发现了一个bug :)


关于Cheekysoft的后续行动:嗯,因为它是应该返回的某种类型的列表,相应的示例应该类似于:

static <T> List<T> createEmptyList( List<T> a ) {
  return new ArrayList<T>();
}

但是,传递类对象显然是更好的。 我唯一的论点就是熟悉,而在这个确切的例子中它并不值得(事实上它很糟糕)。

  ask by pauldoo translate from so

未解决问题?本站智能推荐:

2回复

通用变量类型参数

我想做点什么 获取要在绑定实现中使用的类型数组。 这在Java中可行吗? Varargs旨在让我拥有给定类的任意数量的参数。 我想使用它(或类似的东西)让我的方法接受几个参数,每个参数都是给定不同类的成员。 绑定泛型时定义这些类。 我知道有解决方法,但有一种类型安全的方法吗?
3回复

为什么在泛型类(Java)的构造函数中提供类型参数是错误的?

我只是从教科书中学习Java中的泛型,其中讨论了使用ArrayList<E>实现的GenericStack<E>类。 因为为了创建一个字符串堆栈,您可以使用 要么 因此,不应将GenericStack的构造函数定义为public GenericStack<
3回复

用于Java中看起来很奇怪的显式类型参数声明语法

我最近发现了在调用Java方法时显式声明泛型类型的奇怪语法。 例如: 返回一个空的List<String> 。 但是,这似乎很愚蠢,因为<T> emptyList()的实现只是未经检查的类型转换(List<T>) EMPTY_LIST ,这样所有结果都
3回复

为什么给非泛型方法或构造函数的显式类型参数编译?

在实例化ArrayLists时,我习惯于看到这样的代码 要么 但是今天我遇到了一个如下所示的ArrayList实例: 发生了什么,为什么会给出“不安全的操作”编译警告?
2回复

Java通用类型语法

我无法理解上述陈述 getDao(Class clazz)返回D. D具有以下约束 而且,我无法理解。 你能解释一下吗?
2回复

java-通用返回类型?[重复]

这个问题已经在这里有了答案: 在Java中创建泛型类型的实例? 27个答案 我不确定在Java中是否可行。 另外,我无法弄清楚要在Google上查询什么。 无论如何,我想要一个将类(接口或类)作为参数并且方法的返回类型是该类的实例的方法。 我不想在事实之后重新铸造对象。
3回复

当用`new`实例化泛型时,包括类型参数与否之间有任何实际区别吗?

我开始学习Java,并且在我的程序中 和 和 全部编译并产生我期望的输出。 有实际区别吗? 哪个是首选?
2回复

构造函数类型参数在放置*之前的类型是什么意思?

我最近遇到了这种不同寻常的(对我而言)Java语法...这是一个例子: 注意<String, Long>类型参数的定位......它不是在正常类型之后但在之前。 我不介意承认我之前从未见过这种语法。 另请注意,当ArrayList只有1时,有2个类型参数。 类型参数的定位