Well, I have an interface which is;
public interface abc {
public<T extends JPanel> T initalize();
}
And I'm implementing it. Here is thing, when I defining function like:
public class Startup_thePanel extends JPanel implements abc {
public Startup_thePanel initalize() {
return this;
}
}
I'm getting warning on function initalize which is 'Type safety: The expression of type ... needs unchecked conversion to conform to ...'.
I can get rid of this with using suppresswarning but I do not want to use it. What am I missing ?
Thanks in advance...
public interface abc<T extends JPanel> {
public T initalize();
}
public class Startup_thePanel extends JPanel implements abc<Startup_thePanel> {
public Startup_thePanel initalize() {
return this;
}
}
this would make the compiler to know which type of interface your are implementing.
try this
public interface abc<T extends JPanel> {
public T initalize();
}
public class Startup_thePanel extends JPanel implements abc<Startup_thePanel> {
private static final long serialVersionUID = 1L;
#Override
public Startup_thePanel initalize() {
return this;
}
}
Related
I am trying to build one page assembler using generic approach. Following is piece of code.
In this code IEntity is marker interface for DB entities.
public abstract class PageHrefBuilder implements HrefBuilder<IEntity, PageLinks> {
#Override
public PageLinks buildLinks(IEntity entity) {
return null;
}
}
public interface HrefBuilder<E extends IEntity, L extends Links> {
public L buildLinks(E dto);
}
So we have one interface says can build links using IEntity type of class and return Links type of value. So I want to write some common code in abstract class and abstract class does not know what type entity it suppose to deal with.
For example entity can UserEntity, OrderEntity and so on.
So my question is how in abstract class I can get the class instance to build links with using instanceof or if else approach.
Could someone help me on this.
You can make your buildLinks method to take Class<T> parameter instead of the object you have to pass.
so it will be
public L buildLinks(Class<E> dto);
then in your abstract class
#Override
public PageLinks buildLinks(Class<IEntity> dto) {
return dto.newInstance();
}
Hope this answer could help you.
This got a bit over-engineered but it works and all generics are proper. Hopefully it shows you how you can build your solution:
public class GenericsSample {
public abstract class Links {
String data;
public Links(String data) {
this.data = data;
}
}
public class UserLinks extends Links {
public UserLinks(String data) {
super(data);
}
}
public class PageLinks extends Links {
public PageLinks(String data) {
super(data);
}
}
public abstract class IEntity<L extends Links> {
public abstract L buildLinks();
}
public class UserEntity extends IEntity<UserLinks> {
#Override
public UserLinks buildLinks() {
return new UserLinks("From UserEntity");
}
}
public class PageEntity extends IEntity<PageLinks> {
#Override
public PageLinks buildLinks() {
return new PageLinks("From PageEntity");
}
}
public interface HrefBuilderInterface<E extends IEntity<L>, L extends Links> {
public L buildLinks(E dto);
}
public class HrefBuilder<E extends IEntity<L>, L extends Links> implements HrefBuilderInterface<E, L> {
#Override
public L buildLinks(E entity) {
return entity.buildLinks();
}
}
public static void main(String[] args) {
new GenericsSample().go();
}
private void go() {
System.out.println(new HrefBuilder<UserEntity, UserLinks>().buildLinks(new UserEntity()).data);
System.out.println(new HrefBuilder<PageEntity, PageLinks>().buildLinks(new PageEntity()).data);
}
}
Also note that thanks to this setup the following is not valid:
System.out.println(new HrefBuilder<PageEntity, PageLinks>().buildLinks(new UserEntity()).data);
You can declare abstract method in abstract class to get new instance of Links interface:
abstract class PageHrefBuilder<E extends IEntity, L extends Links> implements HrefBuilder<E, L> {
#Override
public L buildLinks(E dto) {
L links = newLinks();
// ...
return links;
}
protected abstract L newLinks();
}
and implement getting new instance in realization.
I do have an abstract class with an delegation interface defined:
public abstract class MyAbstractClass extends AsyncLoader {
public interface MyAbstractClassDelegate<M> {
//The parameter in this method should be the concrete subtype of MyAbstractClass
public M performThisCall(MyAbstractClass concreteSubclassOfAbstractClass);
}
private MyAbstractClassLoaderDelegate delegate;
...
}
The Problem is, I do not want the delegate parameter to be MyAbstractClass, instead it should be the concrete subclass. Why? Because the implementation of the delegate needs the concrete subclass for further handling and I don't want to cast it...
I know I could define an Interface in each subclass, but it'll look the same in every subclass except for the parameter type
EDIT
Here is the perfect solution solving exactly what I wanted. Great thanks!
public abstract class MyAbstractClass {
public interface MyAbstractClassDelegate<M, Subtype extends MyAbstractClass> {
public M myMethod(Subtype t);
}
}
Is this possible with java 6 and if yes - how?
My solution would be:
public final class Example<T extends Example<T>> {
public interface Interface<M, Subtype extends Interface<M, Subtype>> {
public M myMethod(Subtype t);
}
}
You have no access to the generic from the outer class inside the interface (because the interface is static) so you have to declare it again.
If you use your interface you get something like this:
private static class Impl1 implements Interface<String, Impl1> {
#Override
public String myMethod(final Impl1 t) {
return null;
}
}
I don't know if it will help but here is my complete example:
public final class Example<M, T extends Example.Delegate<M, T>> {
public interface Delegate<M, Subtype extends Delegate<M, Subtype>> {
public M myMethod(Subtype t);
}
private T delegate;
private static class Impl1 implements Delegate<String, Impl1> {
#Override
public String myMethod(final Impl1 t) {
return null;
}
}
public static void main(String[] args) {
Example<String, Impl1> example = new Example<>();
example.delegate = new Impl1();
example.delegate.myMethod(example.delegate); //works but whout?
}
}
What you could do is to give your abstract class a type parameter with the concrete subclass, similar to the way Java's Enum does it.
Something along the lines of this:
public abstract class MyAbstractClass<S extends MyAbstractClass<S>> extends AsyncLoader {
public interface MyAbstractClassDelegate<M, S> {
public M performThisCall(S concreteSubclassOfAbstractClass);
}
...
This is my code:
public interface InterfaceA<J>{
// …
}
public interface InterfaceB extends InterfaceA<String> {
// …
}
public interface InterfaceC extends InterfaceA<Long>{
// …
}
public class Creator<J, I extends InterfaceA<J>> {}
public abstract class Base<J, J1> implements InterfaceA<J> {
protected Creator<J, J1> creator;
protected Base() {
creator=ObjectCreator.createCreator();
}
}
public class Extension1 extends Base<Integer> implements InterfaceB {
// …
}
public class Extension2 extends Base<Double> implements InterfaceC {
// …
}
I want Extension1 to have Creator<Integer, InterfaceB> and Extension2 to have Creator<Double, interfaceC>. See the pattern? Creator<T1, T2> where T1 is the type of immediate parent and T2 is the interface implemented by said class. Is there any way to do this? can anybody tell the code of ObjectCreator.createCreator()?
Right now my code looks like this:
public class ObjectCreator {
public static <J, I extends InterfaceA<J>> Creator<J, I> createCreator() {
return new Creator();
}
}
I got errors all over my code. I'm really confused. What am I missing here?
There's a whole bunch of stuff you missed, a compiling version would look something like this:
package scratch;
interface InterfaceA<J> {
// …
}
interface InterfaceB extends InterfaceA<String> {
// …
}
interface InterfaceC extends InterfaceA<Long> {
// …
}
class Creator<J, I extends InterfaceA<J>> {
}
abstract class Base<J, I extends InterfaceA<J>> {
protected Creator<J, I> creator;
protected Base(Class<J> jClass, Class<I> iClass) {
creator = ObjectCreator.createCreator(jClass, iClass);
}
}
class Extension1 extends Base<String, InterfaceB> implements InterfaceB {
protected Extension1() {
super(String.class, InterfaceB.class);
}
}
class Extension2 extends Base<Long, InterfaceC> implements InterfaceC {
protected Extension2() {
super(Long.class, InterfaceC.class);
}
}
class ObjectCreator {
public static <J, I extends InterfaceA<J>> Creator<J, I>
createCreator(Class<J> jClass, Class<I> iClass) {
return new Creator();
}
}
In no particular order of importance:
When you have a class with a signature like createCreator() has, you need to pass Class objects as type tokens to it. The Java compiler can't infer the types based on the type of the variable you're assigning the return value to. Besides, you want them there anyway because of type erasure, otherwise you couldn't specialise the Creator based on the given types.
If you have Base<J, I> with two type parameters, extending classes should use both of those type parameters.
Your extension class signatures were odd. You can't have class Extension1 extends Base<Integer, InterfaceA<String>>, because you can't have a Creator<Integer, InterfaceA<String>>. Using explicit type tokens in createCreator() would have forced you to propagate this constraint everywhere it needs to be and made the error less mysterious. You can't really make Base independent of the constraint between the J and I type parameters.
Let's say I have:
public class Components<T> extends TupleList<Class<T>, String> {
private static final long serialVersionUID = 1L;
public void add(Class<T> classe, String name) {
this.add(new Tuple<Class<T>, String>(classe, name));
}
}
I'd like to be able to do the following:
Components<IFilter> engines=new Components<IFilter>(){{
add(FilterEngineIdentity.class, "Identity");
}};
where FilterEngineIdentity implements IFilter. How would I achieve this without binding my class Components to more specific class definitions?
Edit: It works! See my test added on the bottom.
Would the following work?
Class<? extends T>
Whole class:
public class Components<T> extends TupleList<Class<?extends T>, String> {
private static final long serialVersionUID = 1L;
public void add(Class<? extends T> classe, String name) {
this.add(new Tuple<Class<? extends T>, String>(classe, name));
}
}
The test (compiles without problems on my machine, Java 1.7 but I didn't use the <> so it should work fine with other versions):
public interface Interface {}
public class Test<T>
{
public void add(Class<? extends T> x)
{
}
public static void x()
{
Test<Interface> t = new Test<Interface>();
t.add(Implementation.class);
}
public static class Implementation implements Interface{}
}
Now that I understand what you're looking for, I think this is more clear and typesafe:
public interface Interface {
}
public class Test<T> {
public <K extends T> void add(Class<K> x) {
}
public static void x() {
Test<Interface> t = new Test<Interface>();
t.add(Implementation.class);
}
public static class Implementation implements Interface {
}
}
I have a base class that has an abstract getType() method. I want subclasses to be able to implement this method and provide the actual class to use.
In code, something like the following:
public abstract class A {
public static interface Tile;
protected abstract Class<Tile> getTileClass();
}
public class B extends A {
public static class MyTile implements A.Tile { }
#Override
protected abstract Class<A.Tile> getTileClass() {
MyTile t = new MyTile(); // WORKS
return MyTile; // ERROR HERE
}
}
The problem here is that I get "MyTile cannot be resolved" in the line marked. So I'm trying to return this instead:
return new MyTile().getClass()
but now Eclipse tells me:
Type mismatch: cannot convert from
Class<capture#1-of ? extends B.MyTile>
to Class<A.Tile>
which I'm not even sure if there's maybe a bug in Eclipse here top (capture#1?).
Next, I'm giving up on interfaces and trying to use an abstract base Tile class. With some help from Eclipse, I end up with the following code that seems to compile:
public abstract class A {
public static abstract class Tile;
protected abstract Class<? extends Tile> getTileClass();
}
public class B extends A {
public static class MyTile exends A.Tile { }
#Override
protected abstract Class<? extends A.Tile> getTileClass() {
return new MyTile().getClass(); // WORKS
return MyTile; // "Cannot be resolved"
}
}
So I basically seem to have three questions:
1) Is it possible to get this to work with A.Tile being an interface?
2) When using a base class, is Class<? extends X> really the correct way to go?
3) And how can I return my nested B.MyTile class reference from inside the method? Having to do new MyTile().getClass() can't be right, can it?
Generics and covariant type overriding do not work very well together. You have to explicitly declare getTileClass() as returning a class that can be a subclass of A.Tile.
You also can access the class object of MyTile without instanciating it, with MyTile.class.
Try this instead:
public abstract class A {
public static interface Tile;
protected abstract Class<? extends Tile> getTileClass();
}
public class B extends A {
public static class MyTile implements A.Tile { }
#Override
protected Class<MyTile> getTileClass() {
return MyTile.class;
}
}
Even better would be to make A generic. You still have to use extends in the class type definition, but you can be a bit more specific:
public abstract class A<T extends A.Tile> {
public static interface Tile;
protected abstract Class<? extends T> getTileClass();
}
public class B extends A {
public static class MyTile implements A.Tile { }
#Override
protected Class<MyTile> getTileClass() {
return MyTile.class;
}
}
public abstract class A {
public static interface Tile {};
// I return something that is-a Tile
protected abstract Tile getTileClass();
}
public class B extends A {
public static class MyTile implements A.Tile { }
#Override
protected abstract Tile getTileClass() {
return new MyTile();
}
}
No need for generics, you just want to say that you return a Tile or Tile subclass.
Incidentally, a public static interface in a class is a "code smell"; either make it protected, so only subclasses of A can implement Tile, or put it in its own top-level interface. Putting in a but allowing anyone to implement it sends a mixed message.