简体   繁体   English

Java泛型类可以在实例化时自动确定类型吗

[英]Can java generic class automatically determing type at instantiation

I have a generic class: 我有一个通用类:

public class ResultCard<T extends Bike>

private T bike;

public ResultCard(T bike)
{
    this.bike = bike;
}

public int someMethod()
{
     bike.showSpeed();
}

Then I have several classes which extend Bike. 然后我有几个班级扩展了Bike。 When I tested out the ResultCard bean I was very surprised that I can instantiate it without specifying the type: 当我测试ResultCard bean时,我很惊讶地可以在不指定类型的情况下实例化它:

ResultCard resultCard = new ResultCard(bikeType);

and the following call worked: 并且以下调用有效:

resultCard.someMethod();

I figured that ResultCard would be instantiated with the Object type as its generic since I didn't specify it when instantiating and then the call to someMethod() would throw a compile time error? 我认为ResultCard会以Object类型作为其泛型进行实例化,因为在实例化时未指定它,然后对someMethod()的调用会引发编译时错误? But that didn't happen. 但是那没有发生。 As if it determines the type from my constructor or something? 好像它从我的构造函数中确定类型一样?

Is there anything wrong with not specifying the generic type when instantiating my bean? 实例化bean时未指定泛型类型有什么问题吗? Am I misunderstanding something? 我误会了吗?

Thank you. 谢谢。

When you have a generic type parameter with a type bound, as in ResultCard<T extends Bike> , the type parameter is replaced by the bound during compilation. 当具有类型绑定的通用类型参数时,如ResultCard<T extends Bike> ,在编译过程中,类型参数将由绑定替换。 It doesn't matter if you create an instance of a raw type new ResultCard(...) or a parameterized type new ResultCard<SomeBike>(...) . 创建原始类型new ResultCard(...)或参数化类型new ResultCard<SomeBike>(...)的实例都没关系。 After compilation the result will be the same. 编译后,结果将相同。

Only if you remove the type bound, the type parameter will be replaced by Object as you expected. 仅当删除类型绑定时,type参数才会按预期被Object替换。

What you see is a so-called raw type . 您看到的是所谓的原始类型 Its behaviour is close to ResultCard<Bike> , but there are some gotchas you need to know about (see pg. 36). 它的行为接近ResultCard<Bike> ,但是您需要了解一些陷阱 (请参阅第36页)。 For example, if you used generics in any overloaded method in this class, eg int addNotes(Collection<Object> notes) and void addNotes(List<Note> notes) , these two will turn into int addNotes(Collection notes) and void addNotes(List notes) , which is likely to change the way the resolution works. 例如,如果您在此类的任何重载方法中使用了泛型,例如int addNotes(Collection<Object> notes)void addNotes(List<Note> notes) ,则这两个将变成int addNotes(Collection notes)void addNotes(List notes) ,这很可能会改变分辨率的工作方式。

Additionally, as raw types lack the additional type information, the code depending on generic tricks will fail to compile. 另外,由于原始类型缺少其他类型信息,因此依赖于通用技巧的代码将无法编译。 For example, class Class<T> is a generic class parametrised with the class it represents. 例如,类Class<T>是用其表示的类参数化的泛型类。 As a result, you can define methods that take an instance of Class<T> as a parameter and return T , knowing that it is that same class you've passed. 结果,您可以定义将Class<T>的实例作为参数并返回T ,知道这是您传递的同一类。 If though you save it to a variable of type Class (no type parameter) , the convenient code will fail to compile in a bit obscure way. 如果将其保存到Class类型(没有类型参数)的变量中 ,则方便的代码将无法以某种晦涩的方式进行编译。

As you have not specified the generic type when instantiating,It is raw type. 由于在实例化时尚未指定通用类型,因此它是原始类型。

To create a parameterized type of ResultCard 创建参数化类型的ResultCard

ResultCard<Bike> resultCard= new ResultCard<Bike>();

If the actual type argument is omitted, you create a raw type 如果省略实际类型参数,则创建一个原始类型

ResultCard rawResultCard = ResultCard();

Hence ResultCard is the raw type of the generic type ResultCard You can always use the rawtype for your generic type. 因此,ResultCard是通用类型ResultCard的原始类型。您始终可以将rawtype用于通用类型。

Did you know!!!! 你知道吗!!!! We did not have List class as generic.But after some time it was given support for generic List.so for backward compatibility still one can use List yet. 我们没有将List类作为通用类,但是经过一段时间后,它获得了对通用List。的支持,因此为了向后兼容,仍然可以使用List。

Here as you have specifed paramitrized type, It allows to instantiate it with the Bike Class parameter and also allows to call the method. 在这里,您已经指定了准类型,它允许使用Bike Class参数实例化它,还允许调用该方法。

But instead if it would have been some other class which does not extend the Bike class, then it will give compile time error. 但是如果不是其他类不能扩展Bike类,那么它将给出编译时错误。

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

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