I have the following Java class with multiple level of inheritance with certain type parameters. I want to use the type parameter T in class B.
class B extends C {
}
class C<T extends D> {
}
class D {
}
However, he following doesn't compile:
class B extends C {
T t;
}
class C<T extends D> {
}
class D {
}
Although I can define the variable t in class C, but it is not a good coding practice. How can I define the following (This doesn't compile as well)?
class B extends C<T extends D> {
}
Thanks!
Type parameters are not inherited!
If you want to have your class B generic, you should specify its own type parameter:
class B<T extends D> extends C<T> {
T t;
...
}
Note that you must again constrain the type parameter T to have it extending D because it is constrained this way in class C.
It should be :
class B<T extends D> extends C<T> {
}
Related
Say I have an abstract class A
public abstract class A<T extends SomeClass, R extends SomeClass> {
...
}
And I have another class B
public class B<S extends A> {
...
}
How can I access T and R within B?
When I try
public class B<F,G,S extends A<F,G>> {
It gives the Error
error: type argument K#1 is not within bounds of type-variable K#2
public class B<F,G,S extends A<F,G>> {
^
where K#1,K#2 are type-variables:
K#1 extends Object declared in class B
K#2 extends SomeClass declared in class A
As long as #JohannesKuhn doesn't post his comment as an answer:
The solution is class B<T extends SomeClass, R extends SomeClass, S extends A<T, R>>
I want to bind the type parameter of the child classes. Let's suppose these are the classes:
class A {}
class B extends A {}
class C extends A {}
I want to bind the above classes so if someone creating a class should only be able to pass self class name. Eg:
class B extends A<B> {} // valid
class C extends A<B> {} // invalid
class C extends A<C> {} // valid
The closest I could get to this is:
class A<T extends A<? super T>> {}
class B extends A<B> {}
class C extends A<B> {} // allows it, but I don't want to allow this.
How can this be achived?
Use case:
class A<T extends A<? super T>> {
private T t;
private A() {}
protected A(T t) {this.t = t;}
public T something() { return t; }
}
class B extends A<B> {
public B(B b) {super(b);}
public B anotherthing() { return this.something(); }
}
There's no way to do this at compile-time.
If you really want, you can enforce it at run-time (preventing problematic classes from being instantiated) by adding logic to A's non-private constructor:
protected A(T t) {
validateClass(getClass());
this.t = t;
}
private static void validateClass(final Class<?> clazz) {
final Type superclass = clazz.getGenericSuperclass();
if ((superclass instanceof ParameterizedType)
&& ((ParameterizedType)superclass).getRawType() == A.class
&& ((ParameterizedType)superclass)getActualTypeArguments()[0] == clazz
) {
// OK
} else {
throw new IllegalStateException(
clazz + " does not extend A<" + class.getName() + ">");
}
}
. . . but I don't think that's a great idea.
In general, although Java provides lots of features for compile-time protections, a Java program ultimately relies on developers to voluntarily write correct code. Many aspects of class contracts are documented, but not enforced. (For example, nothing forces the hashCode() and equals() methods to be consistent with each other; but if you're writing Java code, you'll read the documentation of those methods before overriding them, so will know what you need to do.) In your case, you're best off just telling developers that subclasses of A should pass themselves as the type argument to A, giving them an example, and trusting them to do it.
i have the following Problem. I have a Interface
public interface A<T extends B>
{
T getObject();
}
And i have a class using this interface:
public void test()
{
A<B> a;
B b = a.getObject();
}
This causes an compile error cause the returned Object is B and not extending B.
Is there any way i can declare variable b with ?
Thanks,
Gertrude
I have the following sample code and produce a "type parameter is not within its bound" error on the last line. Class C/D reuses lots of code from A/B thru the inheritance. How would I defined class Y to not have the error and still uses class D for type parameter? Is there a way I can define class D to use A.B but still has the signature of D extends S for class Y?
public abstract class S<E extends S<E>> extends somethingElse {}
public abstract class R<E extends S<E>> {}
public class A extends Z {
public class B extends S<B> {
}
}
public class C extends A {
public class D extends A.B {
}
}
public class X extends R<B> {} // OK
public class Y extends R<D> {} // Error: Type parameter D is not within its bound; should extends S<D>
Any help would be appreciated.
To get this to compile, you can change E extends S<E> to E extends S<? super E>:
public abstract class R<E extends S<? super E>> {}
The cause of this problem is similar to another question that I answered earlier today.
Without the bounded wildcard, D was extending S<B> instead of S<D>.
I have class structure like this:
class A1,A2,..,An extends A;
class B1,B2,..,Bn extends B;
And class that converts Ai into Bi:
private B1 convert(A1 a1){}
...
private Bn convert(An an){}
How can I define single public method with signature like <? extends B> convert(<? extends A> a)?
Now I have only this approach:
B convert(A a){
if(A.getClass().equals(A1.class)){
return convert((A1)a);
}...
}
Can I use instanceof if perfomance is important and the method will be called frequently?
A more elegant solution will probably be to declare a method in A: [preferably abstract, if A is abstract]:
public abstract B toB();
Overriding classes (A1,A2,...) will have to override it and instantiate their own B object.
Code snap [the static modifier is used since I implemented it as an inner class, it is not needed and cannot be used if the classes are outer classes]:
public abstract static class A {
public abstract B toB();
}
public static class A1 extends A {
#Override
public B1 toB() {
return new B1();
}
}
public static class B {
}
public static class B1 extends B {
}
you could do something like:
public <AType extends A, BType extends B> BType convert(AType a) {...
But your could have converter interface like:
public interface Converter<AType extends A, BType extends B> {
AType convert(BType b);
BType convert(AType a);
}
Regarding the performance question, you could take a look here