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 {
}
}
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.
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;
}
}
this is a piece of code i'm struggling with.
public class Channel<T extends Something>{
public Channel(){}
public void method(T something){}
}
public class Manager{
private static ArrayList<Channel<? extends Something>> channels
= new ArrayList<Channel<? extends Something>>();
public static <T extends Something> void OtherMethod(T foo){
for(Channel<? extends Something> c : channels)
c.method(foo); // this does not work
}
}
The line that does not work gives me compiler error:
The method method(capture#1-of ? extends Something) in the type Channel<capture#1-of ? extends Something> is not applicable for the arguments (T)
I don't understand this error. If I remove all the generics in Manager class it is working but type unsafe.
How should I do this in correct Java?
You need a type parameter for your method public <T extends Something> void method(T foo)
public class Channel<T extends Something> {
public Channel() {
}
public <T extends Something> void method(T foo) {
}
}
public class Manager {
private static ArrayList<Channel<? extends Something>> channels = new ArrayList<Channel<? extends Something>>();
public static <T extends Something> void OtherMethod(T foo) {
for (Channel<? extends Something> c : channels)
c.method(foo); // this does not work
}
}
That's inherently unsafe.
What happens if you add a Channel<MyThing> to the list, then call OtherMethod() with a YourThing?
You should make the entire class generic (and make the members non-static), and use the same T for the channels and the parameter.
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);
}
...
Let's say I have ClasseA implements I, how do I do something like:
public class Classe<T> {
void function(Class<T> param) {
...
}
}
Classe<I> c=new Classe();
c.function(ClasseA.class);
Since ClasseA implements the interface I, I would like function to accept either a class literal of type ClasseA or a class implementing I.
Something like this should work:
public Class Classe<T extends I> {
void function(Class<T> param) {
...
}
}
There is a good tutorial about generics available here: http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf
A possible solution to your problem:
public class Snippet {
static class Classe<T> {
public void function(Class<? extends T> param) {
System.out.println(param);
}
}
interface I {
}
class ClasseA implements I {
}
public static void main(String[] args) {
Classe<I> c = new Classe();
c.function(ClasseA.class);
}
}
You can specify constraints on the type this way: Classe<T extends I>