我有一个界面Message
,其中有两个实现MessageA
和MessageB
。
现在我有以下泛型类,它采用扩展T
的类型变量Message
。如果参数是test
(或子类型),我希望方法T
以一种方式操作,如果参数是Message
的其他实现,我希望以其他方式操作:
我尝试了这个,但由于删除它无效:
public class MyClass<T extends Message>
{
public Integer test(T m)
{
System.out.println( "This is the good one." );
return m.f(7);
}
public <S extends Message> Integer test(S m)
{
System.out.println("I'm not the good one");
return m.f(7);
}
}
我可以进行明确的类型检查,但我想有一种更清洁的方式来实现我的目标。
修改
我更喜欢使用覆盖或重载,因为在我的项目中,我将有一个类MyClassA implements MyClass<MessageA>
来实现方法test(MessageA m)
。但我想在基础泛型类中实现“错误”的情况。
以下工作:
public class MyClassA extends MyClass<MessageA>
{
public Integer test(Message m)
{
if (m instanceof MessageA)
{
return m.f(7);
}
else
{
System.out.println("Bad type.");
return 0;
}
}
}
但它迫使我在我的通用if-then
的每个实例中都使用print("bad type")
实现MyClass<T extends Message>
块(为了代码重复)。
修改 根据公认的解决方案,我发布了一个功能齐全的minimal example here。
答案 0 :(得分:0)
重载是静态的。它使用编译时对象类型而不是实际的运行时类型。使用Message#test()来覆盖或向代码添加显式类型检查(即instanceof)。
答案 1 :(得分:0)
您可以使用instanceof
关键字测试:
public Integer test(T m)
{
if(m instanceof MessageA || m instanceof MessageB) {
System.out.println( "A subclass of Message instance." );
//your custom process
}else{
System.out.println( "A Message instance." );
//your custom process
}
}
修改强>
由于在Java中实现泛型的方式,您无法找到泛型类在运行时使用的Object类型(泛型类型T不在运行时保留)。 仍然可以使用私有数据成员并在每个Message分支中重载您的测试方法并在泛型类中使用它:
public class MyClass<T extends Message>
{
private Class<T> type;
public MyClass(Class<T> type) { this.type = type; }
public Integer test(T m)
{
return type.test(m);
}
}
答案 2 :(得分:0)
我的回答可能听起来很刺耳,但你的设计似乎有点破碎。
最简单的解决方案是从公共类(可能与您的接口无关)派生MessageA和MessageB,并向您可以调用的此类添加受保护的函数。
或者您创建了第二个界面,并按照以下问题之一进行操作。
请参阅以下SO问题之一: