java 泛型 class 可以在实例化时自动确定类型吗
Can java generic class automatically determing type at instantiation
我有一个通用的 class:
public class ResultCard<T extends Bike>
private T bike;
public ResultCard(T bike)
{
this.bike = bike;
}
public int someMethod()
{
bike.showSpeed();
}
然后我有几个 class 扩展 Bike。
当我测试 ResultCard bean 时,我很惊讶我可以在不指定类型的情况下实例化它:
ResultCard resultCard = new ResultCard(bikeType);
并且以下调用有效:
resultCard.someMethod();
我认为 ResultCard 将使用 Object 类型作为其泛型进行实例化,因为我在实例化时没有指定它,然后调用 someMethod()
会引发编译时错误?但那并没有发生。好像它从我的构造函数或其他东西确定类型?
实例化我的bean时不指定泛型有什么问题吗?我是不是误会了什么?
谢谢。
当你有一个带有类型绑定的泛型类型参数时,如 ResultCard<T extends Bike>
,类型参数在编译期间被绑定替换。创建原始类型 new ResultCard(...)
或参数化类型 new ResultCard<SomeBike>(...)
的实例并不重要。编译后结果一样。
只有当您移除类型绑定时,类型参数才会如您所愿替换为 Object。
你看到的是所谓的raw type. Its behaviour is close to ResultCard<Bike>
, but there are some gotchas you need to know about(见第36页)。例如,如果您在此 class 中的任何重载方法中使用泛型,例如int addNotes(Collection<Object> notes)
和void addNotes(List<Note> notes)
,这两个将变成int addNotes(Collection notes)
和void addNotes(List notes)
,这很可能会改变分辨率的工作方式。
此外,由于原始类型缺少额外的类型信息,依赖泛型技巧的代码将无法编译。例如,class Class<T>
是一个通用的 class 参数化了它所代表的 class。因此,您可以定义将 Class<T>
的实例作为参数和 return T
的方法,知道它与您传递的 class 相同。如果虽然 you save it to a variable of type Class
(no type parameter),方便的代码将无法以有点晦涩的方式编译。
因为你在实例化的时候没有指定泛型类型,所以是原始类型。
创建参数化类型的ResultCard
ResultCard<Bike> resultCard= new ResultCard<Bike>();
如果省略实际类型参数,则创建一个原始类型
ResultCard rawResultCard = ResultCard();
因此 ResultCard 是泛型 ResultCard 的原始类型
您始终可以将 rawtype 用作您的通用类型。
你知道吗!!!!
我们没有 List class as generic.But 一段时间后,它支持通用 List.so 以实现向后兼容性,但仍然可以使用 List。
这里因为您指定了参数化类型,它允许使用 Bike Class 参数实例化它,还允许调用该方法。
但是如果它本来是其他一些 class 不扩展 Bike class,那么它会给出编译时错误。
我有一个通用的 class:
public class ResultCard<T extends Bike>
private T bike;
public ResultCard(T bike)
{
this.bike = bike;
}
public int someMethod()
{
bike.showSpeed();
}
然后我有几个 class 扩展 Bike。 当我测试 ResultCard bean 时,我很惊讶我可以在不指定类型的情况下实例化它:
ResultCard resultCard = new ResultCard(bikeType);
并且以下调用有效:
resultCard.someMethod();
我认为 ResultCard 将使用 Object 类型作为其泛型进行实例化,因为我在实例化时没有指定它,然后调用 someMethod()
会引发编译时错误?但那并没有发生。好像它从我的构造函数或其他东西确定类型?
实例化我的bean时不指定泛型有什么问题吗?我是不是误会了什么?
谢谢。
当你有一个带有类型绑定的泛型类型参数时,如 ResultCard<T extends Bike>
,类型参数在编译期间被绑定替换。创建原始类型 new ResultCard(...)
或参数化类型 new ResultCard<SomeBike>(...)
的实例并不重要。编译后结果一样。
只有当您移除类型绑定时,类型参数才会如您所愿替换为 Object。
你看到的是所谓的raw type. Its behaviour is close to ResultCard<Bike>
, but there are some gotchas you need to know about(见第36页)。例如,如果您在此 class 中的任何重载方法中使用泛型,例如int addNotes(Collection<Object> notes)
和void addNotes(List<Note> notes)
,这两个将变成int addNotes(Collection notes)
和void addNotes(List notes)
,这很可能会改变分辨率的工作方式。
此外,由于原始类型缺少额外的类型信息,依赖泛型技巧的代码将无法编译。例如,class Class<T>
是一个通用的 class 参数化了它所代表的 class。因此,您可以定义将 Class<T>
的实例作为参数和 return T
的方法,知道它与您传递的 class 相同。如果虽然 you save it to a variable of type Class
(no type parameter),方便的代码将无法以有点晦涩的方式编译。
因为你在实例化的时候没有指定泛型类型,所以是原始类型。
创建参数化类型的ResultCard
ResultCard<Bike> resultCard= new ResultCard<Bike>();
如果省略实际类型参数,则创建一个原始类型
ResultCard rawResultCard = ResultCard();
因此 ResultCard 是泛型 ResultCard 的原始类型 您始终可以将 rawtype 用作您的通用类型。
你知道吗!!!! 我们没有 List class as generic.But 一段时间后,它支持通用 List.so 以实现向后兼容性,但仍然可以使用 List。
这里因为您指定了参数化类型,它允许使用 Bike Class 参数实例化它,还允许调用该方法。
但是如果它本来是其他一些 class 不扩展 Bike class,那么它会给出编译时错误。