【问题标题】:java generics <T extends >java泛型<T扩展>
【发布时间】:2021-12-18 14:39:36
【问题描述】:

TestClass中有一个参数Class t。 t 不能分配给 ClassA.class?

puclic class TestClass<T extends ClassA>{
     private Class<T> t;
     public TestClass(Class<T> t){
        //this.t = ClassA.class;  // why not?
        this.t = t;
     }
}

但是,可以从外部导入。

public class Test{
        public static void main(String[] args) {
              TestClass tc = new TestClass(ClassA.class);//It's ok
        }
}

希望也可以内部赋值!

【问题讨论】:

  • TestClass构造函数中,T是什么类型并不取决于你,所以你不能假设ClassA是合适的。在您的 main 中,它 取决于您,并且您使用的是原始类型,因此无论如何您都放弃了类型检查。
  • 您正在使用自己的泛型类作为原始类型,因此完全禁用了它的泛型部分。你应该这样做TestClass&lt;ClassA&gt; tc = new TestClass&lt;&gt;(ClassA.class); 泛型类的要点是使用它们的人可以声明类型。你可以有一个ClassB extends ClassA,然后在创建你的Testclass 时使用泛型声明它的泛型类型必须是ClassB new TestClass&lt;ClassB&gt;。由于 this.t 的实际类型是动态的,因此您不能简单地将其视为始终是 ClassA,它也可以是扩展该类的任何内容。

标签: java class generics java-8


【解决方案1】:

j.l.Class 上的泛型仅用于使表达式thatClass.newInstance() 具有类型T,例如你可以这样做:

Class<String> c = ...;
String x = c.newInstance();

如果你知道这一点,并且深思熟虑,那么你的人脑,以及关于它的用途的所有上下文知识,就会意识到:

Class<Child> childClass = ...;
Class<Parent> parentClass = childClass;

完全安全。

但是 javac 不能得出这个结论。 Javac 不会成为每个使用泛型的类的通用字典。它只知道如果你允许泛型 generally 是不安全的;它根本不知道 j.l.Class 的任何用法都不会发生不安全的情况。

它很容易出现在列表中。这里:

List<Integer> ints = new ArrayList<Integer>();
List<Number> nums = ints;
Number n = 5.0; // a double
assert n instanceof Double; // true, of course.
nums.add(n); // legal java, of course.
Integer i = ints.get(0); // um.. wait. uhoh.

仔细考虑上面的 sn-p。用java代码编写它并尝试编译它。这是理解泛型不变这一基本原则的关键 - 子类型不能分配给超类型,而不是当我们正在查看的类型 @987654327 @。您可以将:List&lt;Number&gt; 替换为 List&lt;? extends Number&gt;,然后编译会更进一步,但现在 .add() 失败(实际上,您无法向 List&lt;? extends Whatever&gt; 添加任何内容,除了字面意思是 null

【讨论】:

  • 您也不能假设知道Class 的所有用途。我可以轻松添加另一个用例,例如编写一个方法&lt;T&gt; void method(Class&lt;T&gt; c, T obj) { … },如果允许将Class&lt;Child&gt; 分配给Class&lt;Parent&gt;,则将违反TClass&lt;T&gt; 实例的假设。
猜你喜欢
  • 2023-02-02
  • 1970-01-01
  • 1970-01-01
  • 2012-08-30
  • 1970-01-01
  • 2017-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多