Java :如果实现 T(Base)则做某事,如果 "Base" 的任何其他实现则做其他事情

Java : Do something if implementation T (of Base) and something else if any other implementation of "Base"

我有一个接口 Message,它有两个实现 MessageAMessageB

现在我有以下泛型 class,它采用扩展 Message 的类型变量 T。如果参数是 T (或子类型),我希望方法 test 以一种方式运行,如果参数是 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);                                
    }                                                 
}                                                     

我可以进行显式类型检查,但我想有一种更简洁的方法可以实现我的目标。

编辑

我更喜欢使用覆盖或重载,因为在我的项目中,我将有一个 class MyClassA implements MyClass<MessageA> 来实现方法 test(MessageA m)。但是我想在基本泛型 class.

中实现 "wrong" 案例

作品如下:

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;                           
        }                                       
    }                                           
}                                               

但它迫使我在我的泛型 MyClass<T extends Message> 的每个实例化中使用 print("bad type") 实现一个 if-then 块(为了代码重复)。

编辑 基于公认的解决方案,我发布了一个功能齐全的 minimal example here.

重载是静态的。它使用 compile-time 对象类型而不是实际的 run-time 类型。要么使用 Message#test() 来使用覆盖,要么在代码中添加显式类型检查(即 instanceof)。

您可以 测试 使用 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 中的实现方式,您无法找出泛型 class 在运行时使用的对象类型(泛型类型 T 在运行时不保留) ). 仍然,您可以使用私有数据成员并在每个 Message 分支中重载您的测试方法 并在通用 Class 中使用它:

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);                               
    }   

}

我的回答可能听起来很刺耳,但你的设计似乎有点破烂。

最简单的解决方案是从一个公共的 class 派生 MessageA 和 MessageB(这可能与您的界面无关),并向此 class 添加一个受保护的函数,您可以称呼。

或者您创建第二个界面,然后回答以下问题之一。

请参阅以下 SO 问题之一:

Generic extending class AND implements interface

Java generics - Make Generic to extends 2 interfaces