Java generics: parametricise a generic type - java

Good Morning, I am working on some java code and i would like to make something like that:
public class MyClass <E, T extends MyInterface<T<E>>> { }
In this way, T should be both a generic and an instance of a class which implements MyInterface and should be parametric of the type E. But it seems it is not possible in Java, or maybe my approach to the problem is wrong. Thanks in advance.
Update:
First of all thanks to all who replied, now just to make things clear and let You understand what I am trying to achieve, I would like to make a generic container of generic TDAs.
So let's say we need a container of Stacks based on Integers, then I would need to write something like that: MyContainer, of course i need to keep types separated for the insertion part, otherwise i could write MyContainer>. Moreover since all my TDAs implements MyInterface, I would like to set this as bound as well.
So i guess public class MyContainer < E, T extends MyInterface < E>> should do the trick.

This doesn't make sense.
public class MyClass <E, T extends MyInterface<T<E>>> { }
Because of the right-most T. Why would you want to parameterise a class with itself? I think what you really mean is this:
public MyClass<E, T extends MyInterface<E>>
Which essentially means that for every MyClass, you need an E, and a T MyInterface instance which is in turn parameterised to work with E.
I've found beginners can get very carried away with generics, which can result in code which is completely unreadable. Use generics sparingly, and think about whether you really need them in each given instance. If you are finding yourself writing code with multiple levels of nested generics parameterisation, then you're probably doing something wrong in terms of design.

Basically you are trying to do something like this:
class MyClass<T<E>> // T has to be a generic class
or this:
class MyClass<T<Integer>> // T has to be a generic with Integer as parameter
You cannot and shouldnt have to do it, because it's meangingless. It doesn't tell you anything usefull about T. You could use any class as T like this:
DummyClass<T> extends Anything {};
MyClass<DummyClass<Integer>> myClass;

I'm not sure if that's what you want, butI think it could just be
MyClass<E, T extends MyInterface<E>>
T<E> doesn't make much sense to me.

Seems like it should be
public class MyClass <E, T extends MyInterface<E>> { }
Having public class MyClass <E, T extends MyInterface<T<E>>> { }
means that T
should be MyInterface<MyInterface<E>> which doesn't seem likely.
EDIT:
So if you need MyInterface<Class1<Class2>> it seems like it should be something like this:
public class MyClass <A, B extends SomeClass<A>, C extends MyInterface<B> { }
or
public class MyClass <E, T extends MyInterface<SomeOtherClass<E>>> { }

Related

generic interface with bounded generic interface

Say I have generics interface :
public interface MyContainer<E>{
E someMethod();
}
Now I have another interface that I want it to be something like this:
public interface MyService<T extends MyContainer<E>>{
// someMethod goes here
}
It doesn't compile of course, it only compiles like this :
public interface MyService<E,T extends MyContainer<E>>{
// someMethod goes here
}
but I don't like it since MyService interface doesn't care about E it only cares that its type parameter extends MyContainer. Any ideas how to solve it?
but I don't like it
Start liking it.
You must declare type parameters before referencing them, just as you would declare variables before using them.
If you care about the type of E, then you must declare it. The interface MyService does care about E if it's referencing it with T extends MyContainer<E>.
If your interface doesn't care about what E is at all, then you could use an unbounded wildcard.
public interface MyService<T extends MyContainer<?>>
However, every implementation of this interface would need to either redeclare T exactly like this or supply a type argument that satisfies this constraint exactly. You wouldn't be able to get rid of that ?.
Your declaring E and using it as you are is the best solution I can see. Having to type an extra E, is no big problem.

Variable containg a class extending Enum and implementing an interface

I'd like to do something like this:
private Class<? extends Enum<?> implements IMultiBlockEnum> typeEnum;
How would I do that? The "&" instead of "implements" doesn't work, but Eclipse doesn't give a proper explanation either.
Christopher Klinge
You can only use & when declaring an inferred parameter type, like this:
<T extends Enum & IMultiBlockEnum> void x(T a) {}
Wildcard types may not specify a type intersection as an upper bound.
If you start wondering why it is so, consider what would be the return type of typeEnum.newInstance(). It would have to be both Enum<?> and IMultiBlockEnum at the same time.
For the relevant JLS quote please refer to this answer.
P.S. Another thing that makes little sense in your example is that you end up using two independent wildcards, but obviously want it to be captured as the same type.
You can't extend Enum
Enum types are final by design.
You can create your own class using the original Enum as you like without extend it
If you want to require that the implementation be a certain enum, but also implement an interface, you need to define your own enum "class" implementing the interface(s) , e.g.
public enum MyFancyEnum implements IMultiBlockEnum {
A,B,C,D;
// put code to implement IMultiBlockEnum here, e.g.
public void doTheMultiBlockEnumStuff(String input) {
...
}
}
and then declare your variable as a MyFancyEnum, e.g.
private MyFancyEnum typeEnum = MyFancyEnum.C;

How to implement a list of Generic Interfaces

Hello I'm working on some interesting code and a thought has crossed my mind.
Here is some simplified code:
public interface SomeInterFace<T>
{
public List<T> doSomething();
}
Now, I got another interface which should extend this one for various Objects for instance
public interface OtherInterface extends SomeInterface<Integer>,
SomeInterFace<String>, SomeInterface<Number>, ...
Is there a possiblity to write this "OtherInterface" in a manner where it implements "SomeInterface" with a list of objects?
If you are able to handle any type of type argument for OtherInterface, then as others have suggested, you can write:
public interface OtherInterface<T> extends SomeInterface<T>
However, if you need to implement SomeInterface only for a particular list of type arguments (say, String and Number), then you cannot do that. At compile time, SomeInterface<(anything)> just becomes SomeInterface due to type erasure, and the casting is inserted for you after the compiler makes sure you aren't trying to do any unsafe casts (or you've told it not to check). Therefore, you would be trying to write a class that looked something like this:
public interface OtherInterface extends SomeInterface, SomeInterface {
public List doSomething();
public List doSomething();
}
...which is invalid for obvious reasons!
Hope that helps!

Access class name of parameterized type

I have a parameterized class. I would like to get the name of the class represented by the class name. For instance, what I want to do is this:
public T foo(){
System.out.println(T.class.getName());
}
You can't do it this way, since T isn't known at compile time. You could achieve something similar like so:
public void foo(T t) {
System.out.println(t.getClass().getName());
}
Note that this takes an instance of T and would print out the name of its dynamic type.
Whether or not this is a good enough substitute depends on your use case.
Java generics don't work that way. If you have any bounds on T, you can access the bounds by querying the type variable definition. E.g.:
public class Foo<T extends Bar>{}
will let you get at Bar, but not at the subtype of Bar you are actually using. It doesn't work, sorry.
Read the Java Generics FAQ for more info.
BTW: One common solution to this problem is to pass the subtype of T into your class, e.g.
public T foo(Class<? extends T> tType){
System.out.println(tType.getName());
}
I know it's cumbersome, but it's all Java generics allow.
public T foo(T t){
System.out.println(t.getClass().getName());
}

Concrete vs. Bounded Parameterized Type when designing a typesafe API

I would like to hear from you guys on how do you decide when you should be using concrete parameterized type vs. bounded parameterized type when designing API, esp. (that I care most) of defining a class/interface.
For instance,
public interface Event<S>{
void setSource(S s);
}
public interface UserEvent extends EVent<User> // OR: UserEvent<S extends User> extends Event<S>
// It will therefore be void setSource(User s);
}
The problem of using concrete parameter is that, I can't bring this compile-time benefit I earn when using setSource() to a new interface say,
public interface AdminUserEvent extends UserEvent{
void setSource(AdminUser s); // WHERE: AdminUser extends User. This is a method overloading, we also have a void setSource(User s) inherited from UserEvent.
}
What I can work around for this is to do a type checking on the User object when AdminUserEvent.setSource() is called.
Have you ever had this question raised when you design your API? And what are the practices or rules that you will go for when this sort of situation arises? Thanks.
yc
I think your commented-out UserEvent<S extends User> approach is the right one -- then you can declare AdminUserEvent extends UserEvent<AdminUser>. Is that all you need?
If I understand right this does not have much to do with generics in itself, but rather to do with parallel hierarchy. B extends A, BHandler extends AHandler and AHandler.handle(A) but BHandler.handle(B).
Yes, I believe this can be made typesafe with the use of generics. That is, if I have understood your problem correctly.

Categories