Java 扩展泛型类 公共类MyGeneric{} 公共类Extend1扩展了MyGeneric{} 公共类Extend2扩展了MyGeneric{}

Java 扩展泛型类 公共类MyGeneric{} 公共类Extend1扩展了MyGeneric{} 公共类Extend2扩展了MyGeneric{},java,class,generics,subclassing,Java,Class,Generics,Subclassing,就我所知,上面示例中的两个子类都是有效的。我想知道,当子类被实例化时,Java如何知道超类中给定的类型何时被定义,以及它们何时是实际的类名(即,它如何知道T,e不是类名) 旁注,泛型类型是否允许(即使不常见)使用多个字母?如果(由于一些严重的计划错误)类型与现有类冲突怎么办 public class MyGeneric<T, E> {} public class Extend1<T, E> extends MyGeneric<T, E> {} public

就我所知,上面示例中的两个子类都是有效的。我想知道,当子类被实例化时,Java如何知道超类中给定的类型何时被定义,以及它们何时是实际的类名(即,它如何知道T,e不是类名)

旁注,泛型类型是否允许(即使不常见)使用多个字母?如果(由于一些严重的计划错误)类型与现有类冲突怎么办

public class MyGeneric<T, E> {}

public class Extend1<T, E> extends MyGeneric<T, E> {}

public class Extend2 extends MyGeneric<String, Object> {}
公共类E{}
公共类Foo{}
然后呢

编辑:谢谢你这么快的回答。 回答我的第一个问题,这是最有效的

为了回答这个问题

我想知道,当子类实例化时,Java如何知道何时定义超类中给定的类型,以及何时它们是实际的类名(即,它如何知道T,e不是类名)?

Java不在乎。如果你这样做

public class E{}
public class Foo<E>{}
类似问题:


    • 以下方面没有问题:

      class MyGeneric<String> extends java.util.ArrayList<String> {
          String value;
      }
      
      class Test {
          public static void main(String... args) throws Exception {
              MyGeneric<Integer> obj = new MyGeneric<Integer>();
              obj.value = 5;
              //          ^
              //          |
              //          '--- Assign an integer to what seems to be a String!
          }
      }
      
      公共类E{}
      公共类Foo{}
      

      因为在
      Foo
      的上下文中,
      E
      是一种类型。

      让我们看看这个定义:

      public class E{}
      public class Foo<E>{}
      
      public类Extend1扩展了MyGeneric{}
      
      在这里,
      T
      E
      分别出现两次,并扮演两个不同的角色

      • Extend1
        中定义类型参数。这意味着类型
        Extend1
        有两个(无界)类型参数
        T
        E
        这告诉Java编译器使用
        Extend1
        的人需要指定类型
      • extends MyGeneric
        中,使用先前定义的类型参数。如果这里不知道
        T
        E
        是类型参数,那么
        T
        E
        将是简单的类型引用,即编译器将查找名为
        T
        E
        的类(或接口,…)(并且很可能找不到它们)
      是的,类型参数遵循与Java中任何其他标识符相同的语法规则,因此您可以使用多个字母
      ABC
      ,甚至可以使用容易混淆的名称(使用名为
      String
      的类型参数是合法的,但非常容易混淆)


      单字母类型的参数名称只是一种非常常见的命名策略。

      谢谢,这就把事情弄清楚了(不过我还是读了几遍才明白过来)没问题,欢迎:-)好问题顺便说一句。我看到其他问题问为什么
      类MyList扩展ArrayList
      不能像预期的那样工作:-)为了澄清-如果你在其中输入了一个类型名,比如String,那么当引用MyGeneric对象时,String不再意味着java.lang.String,它现在意味着“我命名的某个泛型String”因此,当使用扩展名扩展通用时,编译器会首先考虑“字符串”类型为ARG(不同于java?Lang.string),而第二个“string”作为第一个类型的引用(@ PigauSuppt:确切地说,它将创建一个类型参数names
      String
      ,该类型参数与
      java.lang.String
      没有实际关系,只是混淆了人们并隐藏了该类型的短名称。
      public class E{}
      public class Foo<E>{}
      
      public class Extend1<T, E> extends MyGeneric<T, E> {}