How resolve this
how change code to get same result
public class myClass
{
List<Drawable> d;
List<Bitmap> b;
public myClass(Integer[] resIDsList)
{
...
}
public myClass(List<? extends Drawable> drawableList) // error occure here
{
d = drawableList;
}
public myClass(List<? extends Bitmap> bitmapList) // and here too
{
b = bitmapList;
}
}
if constructors are same in above?
Define static factory methods, and make the constructor private:
static myClass fromDrawables(List<? extends Drawable> list) {
return new myClass(list, null);
}
static myClass fromBitmaps(List<? extends Bitmap> list) {
return new myClass(null, list);
}
private myClass(List<? extends Drawable> drawables, List<? extends Bitmap> bitmaps) {
// ...
}
(You probably want to add another factory method for the myClass(Integer[]) case; but I hope you get the idea of how to extend the above code for this).
Now you would invoke the factory methods, rather than the constructor:
// Not new myClass(...)
myClass a = myClass.fromDrawables(drawablesList);
myClass b = myClass.fromBitmaps(bitmapsList);
I'd recommend reading Effective Java 2nd Ed Item 1: "Consider static factory methods instead of constructors" for a thorough discussion of this approach.
Due to type erasure, this will not compile. One solution would be to pass the elements to the constructor and simply add them to each respective List.
public myClass(Drawable... drawables) {
d = new ArrayList<>(Arrays.asList(drawables));
}
public myClass(Bitmap... bitmaps) {
b = new ArrayList<>(Arrays.asList(bitmaps));
}
You will need to change your List<Drawable> d; to List<? extends Drawable> d; outside of your method. Do this for your List<Bitmap> b; as well. Afterwards, your class should look like this:
public class myClass
{
List<? extends Drawable> d;
List<? extends Bitmap> b;
public myClass(Integer[] resIDsList)
{
...
}
public myClass(List<? extends Drawable> drawableList) // error occurs here
{
d = drawableList;
}
public myClass(List<? extends Bitmap> bitmapList) // and here too
{
b = bitmapList;
}
}
You could also merge both of those constructors into one if you wanted, with this:
public myClass(List<? extends Drawable> drawableList, List<? extends Bitmap> bitmapList)
{
d = drawableList;
b = bitmapList;
}
Related
I have this quite complex class structure:
public interface SubComponent<T> {...}
public interface Component<T, C extends SubComponent<T>> {...}
public class Control<T, I extends Component<T, ? extends SubComponent<T>>> {...}
Then I have two classes that will hold the current state of the Control and of each Component, like this:
public class ControlState<T, I extends Component<T, ? extends SubComponent<T>>> {
// The state keeps a reference to the Control,
// and a map that holds all the states for each component
private final Control<T, I> control;
private final Map<Integer, ComponentState<T, ? extends SubComponent<T>>> components = new TreeMap<>();
// Has a method to add new components
public void addComponent(int index) {
// Here I have error on the control parameter
ComponentState<T, ? extends SubComponent<T>> state = new ComponentState<>(control, index);
...
}
}
public class ComponentState<T, C extends SubComponent<T>> {
// The component state also has a reference to the Control
// and the index to retrieve the Component from a List in the Control
private final Control<T, ? extends Component<T, C>> control;
private final int index;
public ComponentState(Control<T, ? extends Component<T, C>> control, int index) {
this.control = control;
this.index = index;
}
}
In the addComponent(int index) method the IDE says:
Required type: Control<T, ? extends Component<T, C>>
Provided: Control<T, I>
But, since I is: I extends Component<T, ? extends SubComponent<T>> I don't understand where the issue is, types should be compatible, what am I doing wrong?
As a workaround, I decided to simplify the model by removing the I information from the Control class.
As a result, the structure looks like this:
public interface SubComponent<T> {...}
public interface Component<T, C extends SubComponent<T>> {...}
public class Control<T> {
private final List<? extends Component<T, ? extends SubComponent<T>>> components;
}
public class ControlState<T> {
private final Control<T> control;
private final Map<Integer, ComponentState<T>> components = new TreeMap<>();
public void addComponent(int index) {
ComponentState<T> state = new ComponentState<>(control, index);
...
}
}
public class ComponentState<T> {
private final Control<T> control;
private Component<T, ? extends SubComponent<T>> component;
private int index;
private final Map<Integer, ? extends SubComponent<T>> subComponents = new TreeMap<>();
public ComponentState(Control<T> control, int index) {
this.control = control;
this.index = index;
}
}
That said, I would have preferred to keep that information, but I think I'm in a lucky position, meaning that as long as I tell the user that the components I need must be implementations of these two interfaces, internally I have all the APIs I need (exposed by the interfaces) to make the system work as intended
I believe this should resolve your objective either properly or improperly. Thus, here is my idea.
In the addComponent() method of the ControlState class, you are trying to instantiate the ComponentState class. Now, while doing so, you can omit the Type Argument.
Here, the memory allocation will happen like an object of the ComponentState class without a type argument, i.e. non-generic type, however, the actual object will still be referred to as generic typed.
Moreover, your control object was also not instantiated (either to null or properly)
public class ControlState<T, I extends Component<T, ? extends SubComponent<T>>> {
// The state keeps a reference to the Control,
// and a map that holds all the states for each component
private final Control<T, I> control = null;
private final Map<Integer, ComponentState<T, ? extends SubComponent<T>>> components = new TreeMap<Integer, ComponentState<T, ? extends SubComponent<T>>>();
// Has a method to add new components
public void addComponent(int index) {
// Here I have error on the control parameter
ComponentState<T, ? extends SubComponent<T>> state = new ComponentState(control, index);
}
}
The compiler cannot unify the wildcards of the ComponentState.control field and the ComponentState constructor, thus the type error.
You can fix this by materializing the type the wildcard stands for to match what I stands for in the ControlState.state field:
public class ComponentState<T, I extends Component<T, ? extends SubComponent<T>>> {
private final Control<T, I> control;
private final int index;
public ComponentState(Control<T, I> control, int index) {
this.control = control;
this.index = index;
}
}
You have to adjust the type of the components map accordingly
private Map<Integer, ComponentState<T, I>> components = new TreeMap<>();
and now you can implement ControlState.addComponent as
public void addComponent(int index) {
ComponentState<T, I> state = new ComponentState<>(control, index);
components.put(index, state);
}
Mention, that C extends SubComponent<T> is not the same as ? extends SubComponent<T>. You have to use one of them.
public class ControlState<T, C extends SubComponent<T>, I extends Component<T, C>> {
private final Control<T, C, I> control;
private final Map<Integer, ComponentState<T, C>> components = new TreeMap<>();
public void addComponent(int index) {
ComponentState<T, C> state = new ComponentState<>(control, index);
}
}
public class ComponentState<T, C extends SubComponent<T>> {
private final Control<T, C, ?> control;
private final int index;
public ComponentState(Control<T, C, ?> control, int index) {
this.control = control;
this.index = index;
}
}
public interface SubComponent<T> {}
public interface Component<T, C extends SubComponent<T>> {}
public class Control<T, C extends SubComponent<T>, I extends Component<T, C>> {}
Here are the classes declarations:
public interface IPoint<N extends Number> {
...
}
public abstract class PointP<N extends Number> implements IPoint<N> {
...
}
public class Pointf extends PointP<Float> {
...
}
public interface ISegment<T extends Number, P extends IPoint<T>> {
...
}
public abstract class SegmentP<N extends Number, P extends IPoint<N>> implements ISegment<N, P> {
...
}
public class Segmentf extends SegmentP<Float, Pointf> {
...
}
public abstract class LinesPIterator<N extends Number, S extends ISegment<N, IPoint<N>>> implements Iterable<S>, Iterator<S> {
...
}
public class LinesfIterator extends LinesPIterator<Float, Segmentf> {
...
}
The compiler refuses the Segmentf type in the generic declaration of the LinesfIterator class with the error message:
Bound mismatch: The type Segmentf is not a valid substitute for the bounded parameter <S extends ISegment<N,IPoint<N>>> of the type LinesPIterator<N,S>
However for me everything seems correct. The declaration of the LinesfIterator class seems to me to have the same hierarchical schema as the Segmentf class which compiles without problem.
Is there a solution to this way of doing things?
As already said, your hierarchy seems to be unnecessarily complex and shall be simplified. For example, I see no meaning in Pointf -> PointP -> IPoint the hierarchy.
If you want to fix your issue, you have to allow a subtype ? extends IPoint<N> in the LinesPIterator class, so:
public abstract class LinesPIterator<N extends Number, S extends ISegment<N, ? extends IPoint<N>>>
implements Iterable<S>, Iterator<S>
{
// ...
}
Moreover, there would be better to implement only Iterable as long as it provides an Iterator and you might end up with duplicated implementation.
public static class LinesfIterator extends LinesPIterator<Segmentf, Pointf, Float> {
#Override
public Iterator<Segmentf> iterator() {
return new Iterator<Segmentf>() {
#Override
public boolean hasNext() { /* TO DO */ }
#Override
public Segmentf next() { /* TO DO */ }
};
}
}
This remark on the use of an anonymous class rather than a direct use really caught my attention because intuitively, when I can avoid going through an anonymous class I do. On the one hand because it is an additional instantiation and on the other hand because it is more difficult to identify at debug (when they are several in the same class).
And I can't see the reasons why I should prefer the use of an anonymous class for this case.
Maybe with my classes as an example the explanation will be easier.
for(Segmentf segment : new LinesfIterator(cube.getPoints(), cube.getIndices())) {
System.out.println(segment);
}
public abstract class LinesPIterator<N extends Number, S extends ISegment<N, ? extends IPoint<N>>> implements Iterable<S>, Iterator<S> {
private N[][] points;
private int[] indices;
private int count;
public LinesPIterator(N[][] points, int[] indices) {
super();
this.points = points;
this.indices = indices;
}
protected abstract S instanciateIteration(final N[] pointDeb, final N[] pointFin);
#Override
public Iterator<S> iterator() {
return this;
}
#Override
public boolean hasNext() {
return count < (indices.length - 1);
}
#Override
public S next() {
return instanciateIteration(points[indices[count++]], points[indices[count++]]);
}
}
public class LinesfIterator extends LinesPIterator<Float, Segmentf> {
public LinesfIterator(Float[][] points, int[] indices) {
super(points, indices);
}
#Override
protected Segmentf instanciateIteration(Float[] point1, Float[] point2) {
return new Segmentf(point1, point2);
}
}
Consider this example:
I have 3 interfaces: A, B, C, with methods a(), b(), c(); extending a base interface Intf;
I have a enum with options MyEnum.A, MyEnum.B, MyEnum.C;
I have a class extending this 3 interfaces: X implements A, B, C;
There is a way to implement a method in X like this;
public <T extends Intf> T getType (MyEnum enum)
and the result is the interface A, B or C, that is, accessing only method a(), b() or c()?
EDIT: I want to use it on a builder with fluent api:
X var = X.getType(MyEnum.A).a("value").build();
or
X var = X.getType(MyEnum.B).b("value").build();
but never
X var = X.getType(MyEnum.A).b("value").build(); //ERROR
You could dispatch the enum value, and return a matching instance, as #GhostCat suggested.
You could also invert the lookup, so each enum value provides an appropriate instance of Intf:
Variant 1: singleton instance per enum value
public enum MyEnum {
A(new AImpl()),
B(new BImpl()),
C(new CImpl());
private Intf instance;
MyEnum2(Intf instance) {
this.instance = instance;
}
public <T extends Intf> T getType() {
return (T) instance;
}
}
Variant 2: factory, creating new instances:
public enum MyEnum {
A(AImpl.class),
B(BImpl.class),
C(CImpl.class);
private Class<? extends Intf> type;
MyEnum(Class<? extends Intf> type) {
this.type = type;
}
public <T extends Intf> T getType() {
try {
return (T) type.newInstance();
} catch (InstantiationException | IllegalAccessException ex) {
throw new RuntimeException(ex.getMessage(), ex);
}
}
}
Usage:
A a = MyEnum.A.getType();
B b = MyEnum.B.getType();
C c = MyEnum.C.getType();
If I read your question correctly you want compile-time safety for
public <T extends Intf> T getType (MyEnum enum)
to return A for MyEnum.A, B for MyEnum.B etc.
You can achieve this compile-time safety if you make MyEnum class generic. This does now work with normal enums, but it works with old-fashioned "typesafe enum" pattern.
Assume we have three interfaces AA, BB , CC extending the base interface II:
public interface AA extends II { void a(); }
public interface BB extends II { void b(); }
public interface CC extends II { void c(); }
Now the class TT implements all of these interfaces:
public class TT implements AA, BB, CC {
#Override
public void a() { ... }
#Override
public void b() { ... }
#Override
public void c() { ... }
}
Now let EE be our generic pseudo-enum class, parameterized with some subtype of II:
public class EE<XX extends II> {
public static final EE<AA> A = new EE<AA>();
public static final EE<BB> B = new EE<BB>();
public static final EE<CC> C = new EE<CC>();
}
With these definitions the getType method can be declared as follows:
public <XX extends II> XX getType(EE<XX> enumVal)
This method may only return the type the type which parameterized the enumVal. Meaning
AA type = tt.getType(EE.A);
is valid but
BB type = tt.getType(EE.A);
is not.
One of the ways to implement the getType method would be delegate "conversion" of the TT instance to AA, BB or CC to the corresponding pseudo-enums:
public abstract class EE<XX extends II> {
public static final EE<AA> A = new EE<AA>() {
#Override
public <PP extends AA & BB & CC> AA convert(PP instance) {
return new AA() {
public void a() {
instance.a();
};
};
}
};
public static final EE<BB> B = new EE<BB>() {
#Override
public <PP extends AA & BB & CC> BB convert(PP instance) {
return new BB() {
public void b() {
instance.b();
};
};
}
};
public static final EE<CC> C = new EE<CC>() {
#Override
public <PP extends AA & BB & CC> CC convert(PP instance) {
return new CC() {
public void c() {
instance.c();
};
};
}
};
public abstract <PP extends AA & BB & CC> XX convert(PP instance);
}
You can also return instance directly, without wrapping in an anonymous inner class. But then the result can be force-casted to the other interfaces thus allowing access to other methods.
Finally, the implementation of getType is trivial:
public <XX extends II> XX getType(EE<XX> enumVal) {
return enumVal.convert(this);
}
From what I can see, the compiler won't allow
BB bb = tt.getType(EE.A);
Also
BB bb = (BB) tt.getType(EE.A);
bb.b();
won't work as in "produces ClassCastException in the runtime".
The disadvantages are a pseudo-enum construct and somewhat ugly implementation of convert.
Assuming that we are within class X, you have a local generic parameter, you could think of:
public <T extends Intf> T getType (MyEnum enumVal) {
if (enumVal == MyEnum.A) {
return (A) this;
if (enumVal == MyEnum.B) {
return (B) this;
But you don't gain anything from doing so. Those casts don't matter for the caller side.
Because there is nothing that the compiler could do for you here. You could write
A someA = whatever.getType(someEnum);
But you could as well write
B someB = whatever.getType(someEnum);
with the very same someEnum. And the compiler would be all happy.
If you want to achieve a gain on "compile time safety", you would have to somehow "connect" the argument type to the result type.
I would like to implement generic graph classes. These are what I came up with:
public abstract class VertexBase<V extends VertexBase<V, E>, E extends EdgeBase<V, E>> {
public final HashMap<V, E> inEdges = new HashMap<>();
public final HashMap<V, E> outEdges = new HashMap<>();
}
public abstract class EdgeBase<V extends VertexBase<V, E>, E extends EdgeBase<V, E>> {
public final V fromVertex;
public final V toVertex;
public EdgeBase(V from, V to) {
fromVertex = from;
toVertex = to;
from.outEdges.put(to, get());
to.inEdges.put(from, get());
}
protected abstract E get();
}
Now the problem is that I have to implement Edge::get everywhere:
#Override
protected Edge get() {
return this;
}
And the compiler complains that I am calling overridable method in the constructor.
Is there a way to better implement these?
When you implement new class that extends EdgeBase, you need to replace all E type to Edge and Edge must be extends EdgeBase < V, Edge >, for example:
public class EdgeBaseImpl<V extends VertexBase<V, Edge>> extends EdgeBase<V, Edge> {
...
#Override
protected Edge get() {
return this;
}
}
I have three classes:
class ClassR {}
class ClassA<T extends ClassR>{}
class ClassB<E extends ClassA<T extends ClassR>> extends ClassA<T> {
void foo(T param) {
}
void bar(E param) {
}
}
The third class does not compile unless I change it to
class ClassB<E extends ClassA<T>, T extends ClassR> extends ClassA<T> {
void foo(T bar) {
}
void bar(E param) {
}
}
Is there a way to keep only E parameter I need to pass when creating ClassB, and T being inferred? For example, it would be convenient to use:
new ClassB<ClassA<ClassR>>()
instead of:
new ClassB<ClassA<ClassR>, ClassR>()
This even simpler approach might work for you:
class ClassR {}
class ClassA<T extends ClassR>{}
class ClassB<T extends ClassR> extends ClassA<T> {
void foo(T bar) {
}
void bar(ClassA<T> param) {
}
}
And usage then bypasses any reference to ClassA to become:
class SubR extends ClassR {}
ClassB<SubR> obj = new ClassB<SubR>();
Not sure if this is the answer you want but surely the simplest version reads:
class ClassR {
}
class ClassA<T extends ClassR> {
}
class ClassB<T extends ClassR> extends ClassA<T> {
void foo(T bar) {
}
}
public void test() {
ClassB<ClassR> classB = new ClassB<>();
}
As type E extends ClassA you can safely omit the ClassA type parameter in its declaration.Proper ClassA type parameter is enforced in the second parameter to ClassB. See below code for illustration :
class ClassB<E extends ClassA, T extends ClassR> extends ClassA<T> {
private ClassA ob;
public ClassB(E e, T t) {
super(t);
ob = e;
}
}
Usage sample:
class ClassR {
public ClassR() {};
}
class ClassS extends ClassR {
private int x;
public ClassS(int x) {
super();
this.x = x;
}
}
public static void test() {
ClassS data1 = new ClassS(1);
ClassB <ClassB, ClassS> first = new ClassB<>(null, data1);
ClassS data2 = new ClassS(2);
ClassB <ClassB, ClassS> second = new ClassB<>(first, data2);
}