检查通用实例?

Far*_*mor 5 java oop

您好我有一个方法应该返回不同的结果取决于类型.

我可以这样做来检查泛型类型.

public <T> T search(final String query){
 T returnValue = null;
 if (returnValue instanceof String){ }
 if (returnValue instanceof Integer){ }
 if (returnValue instanceof MyObject){ }
Run Code Online (Sandbox Code Playgroud)

但为什么我不能这样做呢?

public <T> T search(final String query){
 T returnValue = null;
 if (T instanceof String){ }
 if (T instanceof Integer){ }
 if (T instanceof MyObject){ }
Run Code Online (Sandbox Code Playgroud)

调用代码.

String id = myObjcet.<String> search("select ...");
Run Code Online (Sandbox Code Playgroud)

Sim*_*nni 5

Java“通过擦除”实现泛型。这意味着在运行时(几乎)根本不了解泛型。相反,编译器会检查泛型,但实际上它会将所有内容转换为 Object(或最近的泛型边界)。

如果您使用 javap 反编译该方法,您将看到它显示为:

public Object search(...
Run Code Online (Sandbox Code Playgroud)

删除对 T 的每个引用。

这是 Java 中泛型的一个严重限制,这通常也反映在具有以下构造的 JRE 类中:

SomeClass<String> x = new SomeClass<String>(String.class);
Run Code Online (Sandbox Code Playgroud)

需要第三次重复 String (String.class) 的地方,因为构造函数需要知道它正在操作哪个类。

这种范式尽管很糟糕,但可以解决您的问题。

关于泛型的信息实际上包含在 .class 文件中,作为元数据,它们可以使用反射进行检查,并且在一定程度上也可以解析。但是,在像您这样的情况下这是不可能的,但是例如 ORM 在列表 getter 上使用它。例如,使用 Hibernate,这样的吸气剂:

public List<Group> getGroups() {
Run Code Online (Sandbox Code Playgroud)

可以由 Hibernate 检查,以便它知道该列表应该包含 Group 的实例,从而相应地调整其查询。

(然而,即使泛型没有以这种方式实现,T 不是一个实例,它是一个类,写 String instanceof String 同样是错误的。应该是 if (T.equals(String.class)) )