Java 我们是否可以使用泛型仅允许特定类型而不允许任何类型<;T>;?

Java 我们是否可以使用泛型仅允许特定类型而不允许任何类型<;T>;?,java,generics,Java,Generics,假设我有三个独立的公共类(没有IS-A关系)A、B和C。我想在C中定义一个字段,使其类型可以是A或B 目前,我通过如下定义C来实现这一点: class A{} class B{} public class C<T> { private T obj; public C(T param){ if ( !(param instanceof A) || !(param instanceof B) ) {

假设我有三个独立的公共类(没有IS-A关系)A、B和C。我想在C中定义一个字段,使其类型可以是A或B

目前,我通过如下定义C来实现这一点:

class A{} class B{}

public class C<T> {

    private T obj;

    public C(T param){
        if ( !(param instanceof A)
                || !(param instanceof B) ) {
            throw new InvalidParameterException("Only types A and B are allowed!");
        }
        this.obj = param;
    }

} 
class A{}class B{}
公共C类{
私人T obj;
公共C(T参数){
如果(!(参数实例A)
||!(参数实例B)){
抛出新的InvalidParameterException(“只允许类型A和B!”);
}
this.obj=参数;
}
} 

上述代码仅在运行时引发异常。但我更愿意在编译时抛出错误,以生成编译器错误,以防使用a或B以外的任何类型来构造C。

您不能这样做,但可以设置要接受的类型的边界

如果你有

class A extends BaseType {}
class B extends BaseType {}
您可以将类
C
定义为

class C<T extends BaseType> { ... }
C类{…}

接口
作为基本类型工作。

使构造函数私有:

private C(T param){
然后提供静态工厂方法来创建特定类型的实例:

public static <T extends A> C<T> create(T param) {
  return new C<>(param);
}

public static <T extends B> C<T> create(T param) {
  return new C<>(param);
}
publicstaticcreate(T参数){
返回新的C(参数);
}
公共静态C创建(T参数){
返回新的C(参数);
}
这并不妨碍您使用类型
C
;您无法创建它的实例。

您可以使用标记接口:

interface AllowedInC {
    // intentionally empty because it will be used as a mere marker
}

class A implements AllowedInC {
    ...
}

class B implements AllowedInC {
    ...
}

class C<T extends AllowedInC> {
   ...
}
interface AllowedInC{
//故意为空,因为它仅用作标记
}
甲级公司{
...
}
B类工具许可证公司{
...
}
C类{
...
}

只有A类或B类(或实现
AllowedInC
)可用于
C

否。你不能这样做。t扩展A就是你看起来的样子吗?你是以不同的方式处理
A
B
类型的对象,还是它们有一个共同的“接口”(严格来说是概念性的,而不是编译时相关的)?如果是,您可以明确地引入一个接口/抽象类,如果不是,这首先看起来像是一个概念错误。即使可以,它们也几乎无法使用。@Smutje是的,我确实以不同的方式处理这两种对象。但是我想为客户端API的用户提供一个单一的接口,以便他们可以在a或B之间传递任何类型。这正是我将泛型视为最后一个选项的原因。正是以下类型我打算通过A和B符号来引用:A->com.google.gson.JsonElement B->org.w3c.dom.Document它们与任何接口/抽象类都不相关!!谢谢:)因为只有一个参数,所以您也可以使用公共静态C create(T param){return new C(param);}。@Jayanth不,您不能这样写。因为您声明了C作为返回类型?@Jayanth您只能在类型变量的声明中使用extends;但是,
T
不在这里的范围内,因为它是一个静态方法