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.
Related
I have
1) a basic interface,
2) a few classes that implement this interface,
3) and a generic class that I want to accept, as a parameter, any of the implementing classes
I have tried the following:
public class Foo extends Bar<? extends SomeInterface> {
public Foo(List<? extends SomeInterface> someInterfaceList) {
super(someInterfaceList);
}
...
}
I receive the error No Wildcard Expected. Elsewhere in my code I have statements such as List<? extends SomeInterface> and I receive no errors, so why am I running into problems here? How can I fix this problem and still get the desired results?
I have tried search 'No Wildcard Expected' and 'wildcard in class declaration' to no avail. Thanks in advance!
It sounds like you want to declare a generic type argument that you will reference elsewhere. Wildcards only make sense when the type is used only once, and when declaring a generic type parameter for a class this doesn't make any sense.
Try this instead:
public class Foo<T extends SomeInterface> extends Bar<T> {
public Foo(List<T> someInterfaceList) {
super(someInterfaceList);
}
...
}
As your code was written, there was no way for the user of your class to specify the generic type argument for Bar<>, since Foo wasn't itself a generic type.
Further, if this were possible, it would have been possible for the generic argument to Bar<> to be different than the generic argument to List<> -- as long as both types implemented SomeInterface there would not be a compile-time issue with these definitions, but there could have been a much more confusing error message later when you incorrectly assumed that both types must be the same.
So, declare the generic type once as a generic argument to the Foo class, and then use that type (T in my example) elsewhere to refer to that type instead of accepting some new generic type argument that may not refer to the same type.
I'm not exactly sure what you're looking for, so it might help if you could provide a little more detail. Perhaps you could be a little more specific about how you're planning to instantiate and use these objects?
Anyways, I think you might be looking for something like this:
import java.util.List;
public class Foo<T extends SomeInterface> {
public Foo(List<T> someInterfaceList) {
for (T item : someInterfaceList) {
// do something with each item
}
}
}
class Bar<T> {}
interface SomeInterface<T> {
T x(T y);
}
Or, alternatively, you could just use the following for the constructor:
public Foo(List someInterfaceList) {
but you wouldn't have an easy way of getting the type T of the items in the list.
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!
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>>> { }
I have a class defined like so:
public class AddRecordsToolbar<D extends IDataSource<T>, T extends Serializable>
extends AbstractToolbar<D, T>
which my IDE IntelliJ IDEA declares as legal. It looks and feels wrong to me.
I want to declare it like this:
public class AddRecordsToolbar<D extends IDataSource<T extends Serializable>, T>
extends AbstractToolbar<D, T>
however that syntax is illegal thanks to something to do with Javas type erasure.
D extends IDataSource<T> is required by the superclass.
My Class is using Serializable to do a deep copy. Hence the T extends Serializable.
So now on to the Question: If I specify T extends Serializable as the second type parameter for my class will it still enforce T extends Serializable for D as well?
Answering to your question, yes its do.
The order of generic parameter it only in your mind.
If we would rephrase that implementation to:
public class AddRecordsToolbar<T extends Serializable, D extends IDataSource<T>> extends AbstractToolbar<D, T>
you will be not so surprised, and looks that the way it should be.
I will try to find the explanation for this in Java Language Specification (when it will work) but for now that the way it is.
I believe that this is addressed in section 8.1.2 of the java language spec:
The scope of a class' type parameter is the entire declaration of the
class including the type parameter section itself. Therefore, type
parameters can appear as parts of their own bounds, or as bounds of
other type parameters declared in the same section.
Yes. The "T" in the second parameter is the same T as in the first. Nothing world work, otherwise.
This means that
class IFoo extends IDataSource<String>{};
AddRecordsToolbar<IFoo, Integer> x;
Is illegal. Integer and String are both serialisable, but the declaration of AddRecordsToolbar says that the data source has to be a source of the data type in your second parameter. And that second parameter says that it has to be serializable.
why does
public interface ArrayOfONEITEMInterface <T extends ONEITEMInterface>{
public List<T> getONEITEM();
}
compile, but not
public interface ArrayOfONEITEMInterface <? extends ONEITEMInterface>{
public List<?> getONEITEM();
}
what is the difference between ? and T in class and method signatures?
? is a wildcard and means any subclass of ONEITEMInterface including itself.
T is a specific implementation of ONEITEMInterface in this case.
Since ? is a wildcard, there is no relation between your ? in the class declaration and the ? in your method declaration hence it won't compile. Just List<?> getONEITEM(); will compile though.
The first scenario means the entire class can handle exactly one type of Bar per instance.
interface Foo<T extends Bar> {
List<T> get();
}
The second scenario allows each instance to operate on any subtype of Bar
interface Foo {
List<? extends Bar> get()
}
T is a placeholder for a type that will be provided by an implementing or instantiating class.
? is a placeholder saying "I don't know or care what the generic type is" generally used when the work you'll do on the container object doesn't need to know the type.
The reason you can't use '?' in the class/interface definition is because there's the value is saying defining the name of the placeholder (and the type will be provided elsewhere). Putting a '?' doesn't make sense.
Furthermore, the placeholder doesn't need to be T, it can any standard Java variable. By convention, it is one capital character, but need not be.
? allows you to have a list of Unknown types, where as T requires a definite type.
The clause <T extends ONEITEMInterface> is declaring a type parameter named T. This allows your generic type, ArrayOfONEITEMInterface, to refer to the parameter elsewhere. For example you can declare a method like void add(T t).
Without naming the type parameter, how would you refer to it? If you never refer to the type parameter, why is your type generic in the first place? For example, you don't need a parameterized type to do something like this:
public interface ArrayOfONEITEMInterface {
List<? extends ONEITEMInterface> getONEITEM();
}
It doesn't make sense to declare an anonymous type parameter, so it is syntactically illegal.