简体   繁体   English

实例化泛型类型类的子类

[英]Instantiating a sub class of generic type class

I have simple generic class as shown below: 我有一个简单的通用类,如下所示:

public class Test<T extends Number> {

    public void doSomething() {
        Test t = new Test();
        t.getNumber();

    }

    public T getNumber() {
        T d = new Double("1.5"); // I get an compiler error here!
        return d;
    }
}

The getNumber method returns T (which extends Number) and in its implementation it instantiates a Double. getNumber方法返回T(它扩展了Number),并在其实现中实例化一个Double。 The compiler is throwing up an error on the line: 编译器在网上抛出一个错误:

    T d = new Double("1.5"); // I get an compiler error here!

The error is: 错误是:

Incompatible types:
[ERROR] found   : java.lang.Double
[ERROR] required: T

Since T extends Number, I would have expected this to work. 由于T扩展了Number,所以我期望它会起作用。 Am I missing something? 我想念什么吗?

T extends Number, but that does not mean that it extends Double. T扩展了Number,但这并不意味着它扩展了Double。 Double is only one of the known subclasses of Number. Double只是Number的已知子类之一。

在左侧使用通用参数,在右侧使用特定的实现是不正确的。

  1. You should get a compiler warning when you instantiate test. 实例化测试时,应该收到编译器警告。
  2. Imagine that you instantiate Test<Integer> . 想象一下,您实例化了Test<Integer> Then the line in the getNumber method becomes: 然后, getNumber方法中的行变为:

    Integer d = new Double("1.5"); 整数d = new Double(“ 1.5”);

Obviously, it should throw a compiler error. 显然,它应该引发编译器错误。

I think that you should not use a generic type argument - replace your class with: 我认为您不应该使用泛型类型参数-将类替换为:

public class Test {
    public Number getNumber() {
        Number d = Double.valueOf("1.5"); // No compiler error
        return d;
    }
}

Another solution would be to express the condition that you can use any superclass of Double as a type argument, ie: 另一种解决方案是表达您可以使用Double的任何超类作为类型参数的条件,即:

public class Test<T super Double> {
    public T getNumber() {
        T d = Double.valueOf("1.5"); // No compiler error
        return d;
    }
}

A few general tips: 一些一般性提示:

  • Do not box primitive types without a good reason. 没有正当理由,不要装箱原始类型。
  • Do not use new to instantiate boxed primitive types, use the static factory methods in the boxing classes instead. 不要使用new实例化装箱的基本类型,而应在装箱类中使用静态工厂方法。
  • Do not use generic types without a good reason. 没有正当理由,请勿使用泛型类型。 And when you go to the hassle of defining a generic type, do not instantiate it without a type parameter. 而且当您遇到定义泛型类型的麻烦时,请不要在没有类型参数的情况下实例化它。
T d = (T)new Double("1.5");

您必须将强制类型转换为T。即使它解决了您的问题,我也对您的工作感到怀疑。

The generic type definition class Test<T extends Number> means that whoever chooses to create an object of your Test class can choose which type parameter to use. 通用类型定义class Test<T extends Number>意味着选择创建Test类对象的任何人都可以选择要使用的类型参数。 The user chooses, not you as the class implementor. 用户选择而不是您作为类实现者。

This means you can't be sure which type it will be, and thus your getNumber() method can only safely 这意味着您无法确定它将是哪种类型,因此您的getNumber()方法只能安全地进行操作

  • return an object which somehow came in as a T object 返回以某种方式作为T对象进入的对象
  • return null 返回null
  • return an object which some other method returning T gave back. 返回一个返回T其他方法返回的对象。
    • return an object created from a Class<T> (or Class<? extends T> ) 返回从Class<T>创建的对象(或Class<? extends T>
    • return an object from a Collection<T> (or Collection<? extends T> ) Collection<T>返回一个对象(或Collection<? extends T>
    • something similar 相似的东西

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM