为什么向非泛型方法或构造函数提供显式类型参数会编译? [英] Why does giving explicit type arguments to a non-generic method or constructor compile?

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

问题描述

在实例化 ArrayLists 时,我习惯看到这样的代码

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.

  • 这个子句暗示一个非泛型方法可能是潜在的适用于提供显式类型参数的调用.事实上,它可能会被证明是适用的.在这种情况下,类型参数将被忽略.
  • This clause implies that a non-generic method may be potentially applicable to an invocation that supplies explicit type arguments. Indeed, it may turn out to be applicable. In such a case, the type arguments will simply be ignored.

强调我的.

另见 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.

原答案:

当您拥有泛型构造函数并且编译器无法推断正确的类型参数时,通常需要这种调用.例如,考虑以下代码:

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));

您会认为类型推断应该失败,因为类型参数应该具有相同的类型.这里我们传递 StringInteger 类型.但事实并非如此.编译器将 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<?>>

现在,您可能希望将类型参数推断为 Object,然后在这种情况下,您可以提供显式类型参数,如下面的代码所示:

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.

现在,在您的代码中,您已经给出了显式类型参数,但是您正在使用类的原始类型来实例化它:

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();

是构造函数的显式类型参数,编译器可以接受.但问题是,您正在实例化原始类型 ArrayList,这就是编译器发出未经检查警告的地方.如果您将该代码更改为:

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();
}

...即使 test() 是一个非泛型方法.

...even though test() is a non-generic method.

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

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