Java:带有类型参数的泛型类型?

Java:带有类型参数的泛型类型?,java,generics,Java,Generics,我有一门课是这样的: public class MyClass <T extends Model1, X extends Model2> { private CommonMessage<T,X> someMethod() { .... } } 简短答复: 首先,因为CommonMessage是泛型的,所以以非泛型的方式扩展它是非常糟糕的,所以您应该使用M扩展CommonMessage,这样做是因为在类声明中传递给CommonMessag

我有一门课是这样的:

public class MyClass <T extends Model1, X extends Model2> {

    private CommonMessage<T,X> someMethod() {
        ....
    }
}
简短答复:

首先,因为CommonMessage是泛型的,所以以非泛型的方式扩展它是非常糟糕的,所以您应该使用M扩展CommonMessage,这样做是因为在类声明中传递给CommonMessage的类型参数不应该在方法返回类型中再次提及此参数类型,所以方法返回类型应该是M

长答覆:

我知道你们知道这个定义,但有时我们作为人类会忘记简单的事情。首先,我们应该考虑泛型是如何创建的,泛型可以创建具有不同参数类型的类,当它们被另一个类扩展时,或者当我们用新的操作符创建它们时,这些参数类型将被提供,因此,当我们编写类时,我们不知道这些参数的确切类型,我们希望将此决定推迟到以后,这与您在类中所做的事情相矛盾,因为在这里,您的方法是私有的,您不能更改其在子类中的实现继承自您的类。但是要知道,我们可以将您的实现更改为这样的方式,这样可以很好地编译:

public  class MyClass<M extends CommonMessage<T, X>, T extends Model1, X extends Model2> {
    private  M method1(){
        ...
    }
}

public class CommonMessage<T, X>{

}

public class MyMessage<T, X> extends CommonMessage<T, X>{

}
public class Model1{

}
public class Model2{

}
虽然这个实现将被编译,但问题是当您编写私有method1时,您在编写这个类时不知道M的类型,因为当我们想要创建这个类的新实例或从这个类继承另一个类时,它将被传递。那么,您希望在method1中创建并返回什么类型的对象呢?这里您只知道它的类型是M,它扩展了CommonMessage,但在编写您的私有方法1时,您不知道M的确切类型是什么

最重要的是,你不能把这个决定委托给你的子类,因为这个方法是私有的。现在的问题是,当我们不知道M的确切类型时,为什么它被允许并编译得很好?暂时忘记这个问题,在解释正确的方法之后,我会把它弄清楚。那么,正确的方法是什么?想想看,编写子类的人确实知道参数M的类型,他们可以在method1的实现中创建适当的M实例,从该方法返回。那么,为什么不将这个决定委托给子类并使这个方法抽象呢?这完全有道理。简而言之,我们有一些类似的实现:

public abstract  class MyClass<M extends CommonMessage<T, X>, T extends Model1, X extends Model2> {
    public abstract M method1();
}

public class CommonMessage<T, X>{

}

public class MyMessage<T, X> extends CommonMessage<T, X>{

}
public class Model1{

}
public class Model2{

}
public abstract class MyClass<M extends CommonMessage<T, X>, T extends Model1, X extends Model2> {
    private  M method1(){
        return method2();
    }
     abstract M method2();
}

public class CommonMessage<T, X>{

}

public class MyMessage<T, X> extends CommonMessage<T, X>{

}
public class Model1{

}
public class Model2{

}
现在让我们回到我们的问题上来,为什么我向你们推荐的第一个程序编译得很好?为什么允许私有方法的返回类型是泛型的,并在实例化或继承时传递? 因为有很多情况使它正确和恰当。 一种情况是我们的私有方法调用另一个公共方法,该方法返回适当的类型,如下所示:

public abstract  class MyClass<M extends CommonMessage<T, X>, T extends Model1, X extends Model2> {
    public abstract M method1();
}

public class CommonMessage<T, X>{

}

public class MyMessage<T, X> extends CommonMessage<T, X>{

}
public class Model1{

}
public class Model2{

}
public abstract class MyClass<M extends CommonMessage<T, X>, T extends Model1, X extends Model2> {
    private  M method1(){
        return method2();
    }
     abstract M method2();
}

public class CommonMessage<T, X>{

}

public class MyMessage<T, X> extends CommonMessage<T, X>{

}
public class Model1{

}
public class Model2{

}

这是行不通的,您只能在实际类型上定义泛型,但是您可以引入一个带有泛型参数的接口消息,比如:,然后您可以在方法中简单地返回M。如果您正在寻找多重继承,java不允许多重类继承。