Reputation: 1047
I am trying to parameter a class with a type that is whether A or B and nothing else.
Something like
final class ChildClass<A | B> extends MotherClass {
This way I can create a ChildClass<A>
or a ChildClass<B>
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).
Upvotes: 4
Views: 2752
Reputation: 120988
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 "F";
}
}
add the generic type that is going to be bounded by this interface:
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());
}
}
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<A> a = new WithGenerics<>(new A());
a.findName();
WithGenerics<B> b = new WithGenerics<>(new B());
b.findName();
because there can be no type C
that can potentially implement F
.
Upvotes: 2
Reputation: 40047
This way I can create a ChildClass<A> or a ChildClass<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<A> extends MotherClass {
private MyClass() {
}
public static MyClass<Integer> instanceOfInteger() {
return new MyClass<Integer>();
}
public static MyClass<String> instanceOfString() {
return new MyClass<String>();
}
// rest of class here
}
MyClass<Integer> mc1 = MyClass.instanceOfInteger();
MyClass<String> mcs = MyClass.instanceOfString();
Upvotes: 1
Reputation: 204
You might be able to check the class type of T like this:
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)) {
//Do something
} else if (classType.equals(B.class)) {
//Do something
}
}
}
Heres an example of creating an object of Foo..
Foo<A> foo = new Foo<>(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.
Upvotes: 1
Reputation: 12060
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.
Upvotes: 5