代码之家  ›  专栏  ›  技术社区  ›  Sean Owen

用泛型解决IDE警告,class<?>类型

  •  2
  • Sean Owen  · 技术社区  · 15 年前
    class Test1<T> {
      Test1(Class<T> type) {}
    }
    
    class Test2 extends Test1<Class> {
      Test2() {
        super(Class.class);
      }
    }
    

    这是可行的,但我被警告在“中使用原始泛型类型” Test1<Class> “。我明白,但是,把它改成 Class<?> “(哪一个应该是等效的?)在对super()的调用中给出编译器错误--class.class显然属于类型“ Class<Class> “而不是” Class<Class<?>> “。

    所有这些变量似乎都会导致编译错误。

    有人能看到如何解决这个问题吗,这样我总是在类中使用类型参数,因此不会收到IDE警告?这样做似乎更好,即使它按原样工作。 我乐于接受这两个类2的结构变化,只要它保留了基本的意图:test2是一种特殊类型的test1,专门用于“类”对象。

    5 回复  |  直到 15 年前
        1
  •  2
  •   Robert Munteanu    15 年前

    你的警告源于 Class 本身是一个参数化类: public final class Class<T> . 删除警告的最简单方法是 T 类型参数而不是 Class<T> :

    class Test1<T> {
        Test1(T type) { Class<?> classType = type.getClass();}
    }
    
    class Test2 extends Test1<String> {
        Test2() {
            super("");
        }
    }
    
        2
  •  2
  •   Jon Skeet    15 年前

    Class Class<?> 不是 确切地 当量。他们是 语义上 等价的,但后者实际上告诉编译器,“是的,我知道这是一个泛型类型,但我对类型参数一无所知。”前者只是一个原始类型,这通常是一个信号,表明它是尚未迁移到使用泛型的旧代码。

    这包括在 Java Generics FAQ -请参见问题“无界通配符参数化类型和原始类型之间的区别是什么?”在 parameterized types section .

        3
  •  1
  •   cd1    15 年前

    我使用Java1.60Sy14,编译器在编译该代码时不给我任何警告。

        4
  •  1
  •   Eddie    15 年前

    这可能是适合以下情况的时间之一:

    @SuppressWarnings("unchecked")
    class Test2 extends Test1<Class> {
      Test2() {
        super(Class.class);
      }
    }
    

    除非你愿意 总是 使用 Test1<Class> ,我看不到解决此警告的其他方法。(如果你跑步,你可能会得到同样的警告 javac -Xlint:unchecked 但我对此并不乐观。)这里的问题是,你通常(我假设)会使用你的类。 Test1 类是一个以类对象为参数的泛型类。我看不出任何解决办法,所以我认为最好的解决办法是抑制这个特定的警告,这样 真实的 问题会突出。

        5
  •  -1
  •   Yishai    15 年前

    简而言之,没有办法指定类型参数。这是因为类对象(例如,list.class,而不仅仅是class.class)不理解泛型类型参数——它在编译期间被清除。

    我的IDE,Intellij的想法,给出了同样的警告。这是IDE太激进了。您可以使用IDEA抑制警告(它会生成@SuppressWarnings注释),但要解决此问题的代码(如Robert Munteau的巧妙解决方法)确实引入了一些讨厌的设计,只是为了避免出现确实不正确的IDE消息—JDK不会将此情况视为擦除。

    编辑:既然投了反对票,我至少应该证明我的想法是正确的。

    考虑以下几点:

     List.class
    

    它表示类型为的类对象:

     Class<List>
    

    它不能表示以下类型:

     Class<List<?>>
    

    因为它不知道给定的列表是否真的有一个泛型参数或者它将是什么。list.class对象必须表示所有类型,就参数化类而言。

    JDK没有将此视为不安全操作的证据是,如果编译代码,它不会给您任何警告。

    因此,IDE过于敏感。尽管发问者没有指定他使用哪一个IDE,但我用Intellij IDEA 8.1.2看到了这种行为。