为什么给予明确的类型参数的非泛型方法或构造编译? [英] Why does giving explicit type arguments to a non-generic method or constructor compile?

查看:190
本文介绍了为什么给予明确的类型参数的非泛型方法或构造编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当实例的ArrayList我看惯了code这样的

When instantiating ArrayLists I am used to seeing code like this

ArrayList<Type> arr = new ArrayList<Type>();

ArrayList<Type> arr = new ArrayList<>();

不过今天我所遇到的ArrayList的实例,看起来是这样的:

however today I have come across an instantiation of ArrayList that looks like this:

ArrayList<Type> arr = new <Type>ArrayList();

到底是怎么回事?为什么,让不安全操作编译警告?

what is going on, and why does that give an "unsafe operations" compile warning?

推荐答案

编辑:

是的,找到了参考。请参见 JLS和教派; 15.12.2.1 - 识别可能适用的方法

Yes, found the reference. See JLS §15.12.2.1 - Identify Potentially Applicable Methods:

如果方法调用包括明确的类型参数,并且
  构件是一个通用的方法,然后的类型参数的数目等于
  到的方法的类型的参数数量。

If the method invocation includes explicit type arguments, and the member is a generic method, then the number of type arguments is equal to the number of type parameters of the method.


      
  • 这一条款意味着一个的非泛型方法可能是潜在的
      适用于提供明确的类型参数调用。

      事实上,它可能会变成是适用的。的 在这种情况下,该类型
      参数将被忽略。

  •   

重点煤矿。

另请参见 JLS和教派; 15.9.3 - 选择构造及其参数,对于理解构造函数调用是如何解决的。它还提到,上述过程之后进行解析。

Also see JLS §15.9.3 - Choosing the Constructor and its Arguments, for understanding how the constructor invocation is resolved. It also mentions that the above mentioned process is followed for resolution.

原来的答复:

对于此类调用通常是必需的,当你有一个通用的构造函数,编译器不能推断出正确的类型参数。例如,请考虑下面的code:

Such kind of invocation is often required, when you have a generic constructor, and the compiler is not able to infer the correct type arguments. For example, consider the below code:

class Demo<T> {
    public <X> Demo(X[] arg1, X arg2) { 
        // initialization code
        System.out.println(arg1.getClass());
        System.out.println(arg2.getClass());
    }
}

假设你调用一个构造函数是这样的:

Suppose you invoke that constructor like this:

Demo<String> demo = new Demo<String>(new String[2], new Integer(5));

您可能会认为该类型推断应该失败,因为类型参数应该具有相同的类型。在这里,我们传递字符串整数类型。但事实并非如此。编译器推断类型 X 为:

You would think that the type inference should fail, as the type arguments should have same types. Here we're passing String and Integer types. But it doesn't. The compiler infers the type X as:

Object & Serializable & Comparable<? extends Object&Serializable&Comparable<?>>

现在,你可能想要的类型参数被推断为刚对象,那么在这种情况下,你可以提供显式类型的参数,如跌破code:

Now, you might want the type parameter to be inferred as just Object, then in that case, you can provide explicit type arguments, as in the below code:

Demo<String> demo = new <Object>Demo<String>(new String[2], new Integer(5));

这是类似于你如何给予,而方法调用显式类型参数。

This is similar to how you give explicit type argument while method invocation.

现在,在你的code,你给了明确的类型参数,但你使用原始类型的类的实例吧:

Now, in your code, you have given the explicit type arguments, but you're using raw type of the class to instantiate it:

ArrayList<Integer> arr = new <String>ArrayList();

&LT;串GT; 是构造函数的显式类型参数,编译器将与它的罚款。但问题是,你实例原始类型的ArrayList ,而这正是编译器给你选中的警告。如果你改变code为:

The <String> is the explicit type argument for the constructor, and compiler will be fine with it. But the issue is, you're instantiating raw type ArrayList, and that is where compiler is giving your unchecked warning. If you change that code to:

ArrayList<Integer> arr = new <String>ArrayList<>();

该警告将消失。但是,由于的ArrayList 构造不是一个普通的构造函数,类型参数似乎是由构造函数只是忽略。事实上,有没有使用这种类型的参数那里。

The warning will go away. But since ArrayList constructor is not a generic constructor, the type argument seems to be just ignored by the constructor. In fact there is no use of that type argument there.

奇怪的是,这也编译:

public static void test() { }

public static void main(String... args) {
    Main.<Integer>test();
}

...即使测试()是一个非泛型方法。

这篇关于为什么给予明确的类型参数的非泛型方法或构造编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆