Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 未指定泛型和<;之间的编译差异&燃气轮机;在爪哇_Java_Generics - Fatal编程技术网

Java 未指定泛型和<;之间的编译差异&燃气轮机;在爪哇

Java 未指定泛型和<;之间的编译差异&燃气轮机;在爪哇,java,generics,Java,Generics,我觉得这完全令人困惑。出于某种原因,javac似乎对待带有未指定泛型的引用,并且在类型安全方面与不同。有人知道这是为什么(Java1.6)吗 带有GenericMember的公共抽象类{ GenMember getMember(){ 返回(GenMember)null; } GenReturn句柄(处理程序){ 返回handle.handle(); } 接口处理程序{ 公共句柄(); } 静态类ClassWithMember扩展类WithGenericMember{ } 静态类成员类型{ } 静

我觉得这完全令人困惑。出于某种原因,javac似乎对待带有未指定泛型的引用,并且在类型安全方面与
不同。有人知道这是为什么(Java1.6)吗

带有GenericMember的公共抽象类{
GenMember getMember(){
返回(GenMember)null;
}
GenReturn句柄(处理程序){
返回handle.handle();
}
接口处理程序{
公共句柄();
}
静态类ClassWithMember扩展类WithGenericMember{
}
静态类成员类型{
}
静态类句柄类型{
}
公共静态void main(字符串[]argv){
HandledType handled=null;
Handler=newhandler(){
公共句柄类型句柄(){
返回(HandledType)null;
}
};
ClassWithMember混凝土=新的ClassWithMember();
ClassWithGenericMember括号=混凝土;
ClassWithGenericMember NoBlack=混凝土;
handled=concrete.handle(handler);//编译
handled=bracket.handle(handler);//编译
handled=noBracket.handle(handler);//失败:
/*
java:38:不兼容的类型
找到:java.lang.Object
必需:ClassWithGenericMember.HandledType
handled=noBracket.handle(handler);
^
注意:ClassWithGenericMember.java使用未检查或不安全的操作。
注意:使用-Xlint重新编译:未选中以获取详细信息。
*/
}
}

尽管看起来很奇怪,但当您使用原始类型时,所有泛型类型(所有泛型类型,而不仅仅是类的参数化类型)都会从类内的声明中删除(JLS 4.8):

构造函数的类型(§8.8),实例方法(§8.4,§9.4),或 非静态字段(§8.3)M为未继承自 它的超类或超接口是对应的原始类型 在对应于的泛型声明中删除其类型 C

当您将
ClassWithGenericMember noBracket
(“原始类型C”)使用时,
noBracket.handle()
的类型是“与其类型的擦除相对应的原始类型”,即
对象句柄(HandlerType handler)
。(正如您在注释中所说的)“调用不以任何方式使用类的泛型成员类型”并不重要

请注意,这仅适用于直接在类中声明的构造函数、实例方法和非静态字段的类型(例如,非类方法、静态字段、继承方法),并不影响实现中的声明(例如,方法中的声明)

--

这一问题/答案在SO like中出现过几次:


这完全是应该的。原始类型(不带泛型)消除泛型将提供的所有类型安全性,而
表示可以推理的固定但未知的泛型类型。但是调用无论如何都不会使用类的泛型成员类型。编译器错误针对泛型方法,该方法是处理程序指定的不同泛型。
public abstract class ClassWithGenericMember<GenMember> {

  GenMember getMember() {
    return (GenMember) null;
  }

  <GenReturn> GenReturn handle(Handler<GenReturn> handler) {
    return handler.handle();
  }

  interface Handler<GenHandled> {
    public GenHandled handle();
  }

  static class ClassWithMember extends ClassWithGenericMember<MemberType> {
  }

  static class MemberType {
  }

  static class HandledType {
  }

  public static void main(String[] argv) {
    HandledType handled = null;
    Handler<HandledType> handler = new Handler<HandledType>(){
      public HandledType handle() {
        return (HandledType) null;
      }
    };

    ClassWithMember concrete = new ClassWithMember();
    ClassWithGenericMember<?> bracket = concrete;
    ClassWithGenericMember noBracket = concrete;

    handled = concrete.handle(handler); //compiles
    handled = bracket.handle(handler); //compiles
    handled = noBracket.handle(handler); //fails:
    /*
ClassWithGenericMember.java:38: incompatible types
found   : java.lang.Object
required: ClassWithGenericMember.HandledType
    handled = noBracket.handle(handler);
                              ^
Note: ClassWithGenericMember.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
    */
  }
}