当前位置: 首页 > 面试题库 >

Java泛型类型擦除方法参数

滕祯
2023-03-14
问题内容

我是从Joshua Bloch的google I / O困惑者演讲中得到的。这是代码

 public class Glommer<T> {
      String glom(Collection<?> obj){
         String result = "";
         for(Object o : obj){
              result += o;
         }
         return result;
      }

      int glom(List<Integer> ints){
           int result = 0;
           for(int i : ints){
                result += i;
           }
           return result;
       }

      public static void main(String args[]){
           List<String> strings = Arrays.asList("1", "2", "3");
           System.out.println(new Glommer().glom(strings));
      }

这个main方法会引发异常,因为new Glommer它是原始类型,因此in中的所有泛型都将Glommer被删除,因此最终调用int glom(List<Integer> ints)而不是String glom(Collection<?> obj)

我的问题是,即使我打电话glom()new Glommer<Integer>().glom(strings)不是应该把它调用int glom(List<Integer> ints)方法,因为由于类型擦除,这种方法是有效的int glom(List ints)并且strings是类型的List不是Collection


问题答案:

被调用的方法是在编译时定义的,而不是在运行时定义的。

如果在构造函数调用中添加参数,则编译器将具有足够的信息来知道它必须调用第一个方法。否则,就好像泛型不存在一样。在这两种情况下,被调用的方法在运行时将始终保持不变。

编辑有些人似乎对此表示怀疑,所以这是另一个例子:

public class Test {

    private static void test(Object object) {
        System.out.println("Object method");
    }

    private static void test(Integer integer) {
        System.out.println("Integer method");
    }

    public static void main(String[] args) {
        Object object = Integer.valueOf(0);
        test(object);
    }

}

结果是:

Object method

您将Integer传递给方法,但是编译器在编译时所知道的只是它是一个对象。即使对象实际上是整数,jvm也不会自动更改方法调用。



 类似资料:
  • 我有一个返回泛型的函数: 所以,当我试图匹配一个函数结果时,我的问题是: 我得到一个警告:“类型模式数组[CustomerInfo到[CustomerApplication到]]中的非变量类型参数CustomerApplication-DDTO未选中,因为它已被擦除消除。” 这是否意味着在Array[]中可以得到任何类型的数组?所以我已经阅读了关于ClassTag和TypeTag的文章,但是误解了

  • 面对这一行代码,我感到非常困惑: 我知道什么

  • 问题内容: 我有一个方法以a 作为参数。 在中,我如何知道a 是还是a 是? 问题答案: 根据用户omain的回答“如果使用<?>,则意味着您将不会在任何地方使用参数化类型。要么转到特定类型(在您的情况下,似乎是),要么转到非常通用的“ 另外,我相信如果您使用问号,编译器将在运行时(类型;有效Java的第119页)消除类型不匹配的情况,绕过擦除,并有效地消除了使用泛型类型所带来的好处? 要回答发问

  • 问题内容: 我以为Java擦除会在编译时消除泛型类型,但是当我自己对其进行测试时,我意识到在Bytecode中有一些有关泛型类型的信息。 这是我的测试: 我写了2节课: 和 我编译了两个类,并在通用类的某个地方看到了这一行 在非泛型类中: 所以很明显我在字节码中有通用信息,那么这个擦除的东西是什么? 问题答案: 一些通用类型信息存储在属性中。请参阅JLS 4.8 和4.6以及JVM规范4.3.4。

  • 问题内容: 如果在Java中创建泛型类(该类具有泛型类型参数),则可以使用泛型方法(该方法带有泛型类型参数)吗? 考虑以下示例: 正如您对通用方法所期望的那样,我可以使用任何对象调用的实例: 但是,如果我尝试使用 不 指定泛型类型的实例,则无论传入什么,我都会调用返回, 奇怪的是,如果返回类型是通用类,它将编译(例如(实际上,这可以解释-参见下面的答案)): 此外,如果输入通用类,即使仅使用通配符

  • 如果在Java中创建泛型类(该类具有泛型类型参数),是否可以使用泛型方法(该方法采用泛型类型参数)? 考虑下面的例子: 正如您所期望的那样,对于任何对象,的实例,我都可以调用: 但是,如果我试图使用的实例而不指定泛型类型,那么调用将返回一个