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

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

Parameter a class with type A or B

问题

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

类似于:

  1. 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

  1. 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的接口:

  1. sealed interface F permits A, B {
  2. default String name() {
  3. return "F";
  4. }
  5. }

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

  1. static class WithGenerics<T extends F> {
  2. private final T t;
  3. public WithGenerics(T t) {
  4. this.t = t;
  5. }
  6. public void findName() {
  7. System.out.println(t.name());
  8. }
  9. }

最后创建两个类AB

  1. static final class A implements F {
  2. .....
  3. }
  4. static final class B implements F {
  5. .....
  6. }

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

  1. WithGenerics<A> a = new WithGenerics<>(new A());
  2. a.findName();
  3. WithGenerics<B> b = new WithGenerics<>(new B());
  4. 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:

  1. sealed interface F permits A, B {
  2. default String name() {
  3. return &quot;F&quot;;
  4. }
  5. }

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

  1. static class WithGenerics&lt;T extends F&gt; {
  2. private final T t;
  3. public WithGenerics(T t) {
  4. this.t = t;
  5. }
  6. public void findName() {
  7. System.out.println(t.name());
  8. }
  9. }

And finally create the two classes A and B:

  1. static final class A implements F {
  2. .....
  3. }
  4. static final class B implements F {
  5. .....
  6. }

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

  1. WithGenerics&lt;A&gt; a = new WithGenerics&lt;&gt;(new A());
  2. a.findName();
  3. WithGenerics&lt;B&gt; b = new WithGenerics&lt;&gt;(new B());
  4. b.findName();

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

答案3

得分: 1

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

  1. public class Foo<T> extends MotherClass {
  2. private final Class<T> classType;
  3. public Foo(Class<T> classType) {
  4. this.classType = classType;
  5. }
  6. public Class<T> getClassType() {
  7. return this.classType;
  8. }
  9. public void method() {
  10. if (classType.equals(A.class)) {
  11. //做一些操作
  12. } else if (classType.equals(B.class)) {
  13. //做一些操作
  14. }
  15. }
  16. }

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

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

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

英文:

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

  1. public Class Foo&lt;T&gt; extends MotherClass {
  2. private final Class&lt;T&gt; classType;
  3. public Foo(Class&lt;T&gt; classType) {
  4. this.classType = classType;
  5. }
  6. public Class&lt;T&gt; getClassType() {
  7. return this.classType;
  8. }
  9. public void method() {
  10. if (classType.equals(A.class)) {
  11. //Do something
  12. } else if (classType.equals(B.class)) {
  13. //Do something
  14. }
  15. }
  16. }

Heres an example of creating an object of Foo..

  1. 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
那么,为什么不预定义该类以返回允许的任一类型的实例呢?

  1. class MyClass&lt;A&gt; extends MotherClass {
  2. private MyClass() {
  3. }
  4. public static MyClass&lt;Integer&gt; instanceOfInteger() {
  5. return new MyClass&lt;Integer&gt();
  6. }
  7. public static MyClass&lt;String&gt; instanceOfString() {
  8. return new MyClass&lt;String&gt;();
  9. }
  10. // 这里是类的其余部分
  11. }
  12. MyClass&lt;Integer&gt; mc1 = MyClass.instanceOfInteger();
  13. 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?

  1. class MyClass&lt;A&gt; extends MotherClass {
  2. private MyClass() {
  3. }
  4. public static MyClass&lt;Integer&gt; instanceOfInteger() {
  5. return new MyClass&lt;Integer&gt;();
  6. }
  7. public static MyClass&lt;String&gt; instanceOfString() {
  8. return new MyClass&lt;String&gt;();
  9. }
  10. // rest of class here
  11. }
  12. MyClass&lt;Integer&gt; mc1 = MyClass.instanceOfInteger();
  13. MyClass&lt;String&gt; mcs = MyClass.instanceOfString();
  14. </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:

确定