参数一个类型为 A 或 B 的类。

huangapple go评论74阅读模式
英文:

Parameter a class with type A or B

问题

我正在尝试为一个类参数化一个类型,该类型只能是 A 或者 B,不能是其他任何类型。

类似于:

final class ChildClass<A extends MotherClass> extends MotherClass {

这样我可以创建一个 ChildClass<A> 或者一个 ChildClass<B>,但不能是其他类型。

在Java中是否有可能实现?


编辑:

我必须指明我正在使用Java 8,并且我无法控制类A和B(它们是我正在使用的Android框架中的类)。

英文:

I am trying to parameter a class with a type that is whether A or B and nothing else.

Something like

final class ChildClass&lt;A | B&gt; extends MotherClass {

This way I can create a ChildClass&lt;A&gt; or a ChildClass&lt;B&gt; but nothing else.

Is it possible in Java?


Edit:

I must specify that I am using Java 8 and that I have no control of classes A and B (which are classes of the Android framework I am working with).

答案1

得分: 5

很遗憾,它并不是。搜索术语 union types in java 或者 java either type

Java 中最为人所知的联合类型的案例是捕获多个异常,这已经内置在语言中,然而滥用异常来表示自己的类型是不合适的。

这里 也有一个有趣的解决方法。

英文:

Unfortunately is not. Search for term union types in java or java either type.

The most known case of union types in Java is catching multiple exceptions, which is built-in into language, however it would be awful to abuse exceptions for your own types.

Here is also interesting workaround.

答案2

得分: 2

通过添加此JEP,现在有一种相当有趣的方法来实现这一点。

您可以创建一个sealed的接口:

sealed interface F permits A, B {

    default String name() {
        return "F";
    }
}

在这个接口上添加将会被此接口“限定”的泛型类型:

static class WithGenerics<T extends F> {

    private final T t;

    public WithGenerics(T t) {
        this.t = t;
    }

    public void findName() {
        System.out.println(t.name());
    }

}

最后创建两个类AB

static final class A implements F {
    .....
}

static final class B implements F {
    .....
}

这样,您已经有效地指定只有AB可以传递给:

WithGenerics<A> a = new WithGenerics<>(new A());
a.findName();

WithGenerics<B> b = new WithGenerics<>(new B());
b.findName();

因为不可能有一个类型C可能实现F

英文:

With the addition of this JEP, there is a rather interesting way to do it now.

You can create an interface that is sealed:

sealed interface F permits A, B {

    default String name() {
        return &quot;F&quot;;
    }
}

add the generic type that is going to be bounded by this interface:

static class WithGenerics&lt;T extends F&gt; {

    private final T t;

    public WithGenerics(T t) {
        this.t = t;
    }

    public void findName() {
        System.out.println(t.name());
    }

}

And finally create the two classes A and B:

static final class A implements F {
    .....
}

static final class B implements F {
   .....
}

And you have effectively said that only A and B can be passed to :

 WithGenerics&lt;A&gt; a = new WithGenerics&lt;&gt;(new A());
 a.findName();

 WithGenerics&lt;B&gt; b = new WithGenerics&lt;&gt;(new B());
 b.findName(); 

because there can be no type C that can potentially implement F.

答案3

得分: 1

你也许可以像这样检查T的类类型:

public class Foo<T> extends MotherClass {
    private final Class<T> classType;

    public Foo(Class<T> classType) {
        this.classType = classType;
    }

    public Class<T> getClassType() {
        return this.classType;
    }

    public void method() {
        if (classType.equals(A.class)) {
            //做一些操作
        } else if (classType.equals(B.class)) {
            //做一些操作
        }
    }
}

这是一个创建Foo对象的示例:

Foo<A> foo = new Foo<>(A.class);

希望这对您有所帮助,如果不行,请留下评论,我会尽量编辑并提供更有帮助的回答。

英文:

You might be able to check the class type of T like this:

public Class Foo&lt;T&gt; extends MotherClass {
    private final Class&lt;T&gt; classType;

    public Foo(Class&lt;T&gt; classType) {
        this.classType = classType;
    }

    public Class&lt;T&gt; getClassType() {
        return this.classType;
    }

    public void method() {
        if (classType.equals(A.class)) {
        //Do something
        } else if (classType.equals(B.class)) {
        //Do something
        }
    }
}

Heres an example of creating an object of Foo..

Foo&lt;A&gt; foo = new Foo&lt;&gt;(A.class);

Hope this helps you if it doesn't leave a comment and I'll try to edit and provide a more helpful answer.

答案4

得分: 1

这样我就可以创建一个ChildClass<A>或者一个ChildClass<B>,但不能创建其他任何东>西。这在Java中可行吗?
我假设AB是实际的类型,而不仅仅是泛型参数。否则,AB可以是任何东西,所以你可能只需要A
那么,为什么不预定义该类以返回允许的任一类型的实例呢?

class MyClass&lt;A&gt; extends MotherClass {
    private MyClass() {
    }

    public static MyClass&lt;Integer&gt; instanceOfInteger() {
        return new MyClass&lt;Integer&gt();    
    }
    public static MyClass&lt;String&gt; instanceOfString() {
         return new MyClass&lt;String&gt;();
    }
    // 这里是类的其余部分
}

MyClass&lt;Integer&gt; mc1 = MyClass.instanceOfInteger();
MyClass&lt;String&gt; mcs = MyClass.instanceOfString();
英文:

>This way I can create a ChildClass&lt;A> or a ChildClass&lt;B> but nothing else.
Is it possible in Java?

I am assuming that A and B are real types and not just generic parameters. Otherwise, A and B could be anything so you may as well just have A.

So why not just predefine the class to return an instance of whichever ones are allowed?

class MyClass&lt;A&gt; extends MotherClass {
	private MyClass() {
	}
	
	public static MyClass&lt;Integer&gt; instanceOfInteger() {
		return new MyClass&lt;Integer&gt;();	
	}
	public static MyClass&lt;String&gt; instanceOfString() {
         return new MyClass&lt;String&gt;();
	}
    // rest of class here
}


MyClass&lt;Integer&gt; mc1 = MyClass.instanceOfInteger();
MyClass&lt;String&gt; mcs = MyClass.instanceOfString();

</details>



huangapple
  • 本文由 发表于 2020年10月1日 23:45:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/64158822.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定