I don't think this is a duplicate of Check if a generic T implements an interface, but it may be(??).
So, I want to create a generic interface that only allows objects that implements two interfaces. Alike is a costum interface.
public interface AbstractSortedSimpleList<T extends Comparable<T>, Alike> {}
If I understand it correctly, Java now tries to create a generic interface AbstractSortedSimpleList<T,Alike>, which isnt exactly what I want to achieve. I want AbstractSortedSimpleList<T> where T has to implement both Comparable<T> and Alike.
Later, I want to make a new class
public class SortedSimpleList<T> implements AbstractSortedSimpleList<T> {}
The point here is to create a class SortedSimpleList<T> where T has to be implementing the aforementioned interfaces. But my code does not seem to work very well.
You can give multiple bounds to type parameter:
public interface AbstractSortedSimpleList<T extends Comparable<T> & Alike>
Then, your SortedSimpleList would be like:
class SortedSimpleList<T extends Comparable<T> & Alike> implements AbstractSortedSimpleList<T> {}
See JLS §4.4:
Every type variable declared as a type parameter has a bound. If no bound is declared for a type variable, Object is assumed. If a bound is declared, it consists of either:
a single type variable T, or
a class or interface type T possibly followed by interface types I1 & ... & In.
Note:
You can't have such multiple bounds for wildcards though. It's only for type parameters.
References:
Java Generics FAQs - Type Parameter bounds
Use some generic bounds with the & notation
interface AbstractSortedSimpleList<T extends Comparable<T> & Alike> {
See the official Java tutorial on multiple bounds, here.
Related
Notation: Inter is interface; Abs[N] is an abstract class.
The following code works fine in Java without a problem:
public class Impl<T extends Abs1<T>> extends Abs2<T> {...}
However, if you want to introduce another bound by an interface on T, I haven't found any easy way to do it, namely:
public class Impl<T extends Inter & Abs1<T>> extends Abs2<T> {...}
won't work because Abs1 as an abstract class cannot be used as a bounding parameter. The simplest, but ugly (is it ugly?) solution I have found is:
public class Impl<B extends Inter, T extends Abs1<B>> extends Abs2<T> {...}
I have a hunch that in Scala with the traits there exists a more elegant solution, but are there any tips for Java?
Oh my... well, this is embarrassing. I was so focused on the F-Bound, that I forgot that this comes directly from the JLS, section 4.4:
Every type variable declared as a type parameter has a bound. If no bound is declared for a type variable, Object is assumed. If a bound is declared, it consists of either:
a single type variable T, or
a class or interface type T possibly followed by interface types I1 & ... & In.
In other words the (abstract) class declaration must come first in an intersection type. The described behaviour has nothing to do with F-Boundedness. I.e., the following works:
public class Impl<T extends Abs1<T> & Inter> extends Abs2<T> {...}
This is also described in the Java Tutorial. If one thinks about it, it is self-explanatory, hence this way the parser has an easy way to check for double-inheritance (which is prohibited).
Consider
Gen<T>
So, when I write something like this
Gen<Integer> someRef = new Gen<>();
Gen<String> someRef = new Gen<>();
As per my understanding,
The Java compiler does not actually create different versions of Gen,
or of any other generic class. Although it’s helpful for me to think in these terms,
it is not what actually happens. Instead, the compiler removes all generic
type information, substituting the necessary casts, to make my code behave
as if a specific version of Gen were created.
Thus, there is really only one version of Gen that actually exists in my program.
The process of removing generic type information is called erasure.
Now consider this one,
interface MinMax<T extends Comparable<T>> {
In general, a generic interface is declared in the same way as is a
generic class.
In this case, the type parameter is T, and its upper bound is Comparable, which is an
interface defined by java.lang. A class that implements Comparable defines objects
that can be ordered. Thus, requiring an upper bound of Comparable ensures that MinMax
can be used only with objects that are capable of being compared. Notice that
Comparable is also generic. (It was retrofitted for generics by JDK 5.)
It takes a type parameter that specifies the type of the objects
being compared.
Next, MinMax is implemented by MyClass.
Notice the declaration of MyClass, shown here:
class MyClass<T extends Comparable<T>> implements MinMax<T> {
Here comes my confusion,
When I will write something like this,
MyClass<Integer> ......
Type parameter T will be replaced by Integer. or say any other version(depends on type of Objects I will be operating).
I know very well that a class implements an interface. With regard to aforementioned, wouldn't the above case work like this,
class MyClass<Integer(or some other version) extends Comparable<Integer>> implements MinMax<Integer> {
So, how come a class here is extending an interface,
Integer(or some other version) extends Comparable<Integer>
I know for sure, my understanding is not correct regarding the above context. Kindly elaborate?
The reason is that in Generics the keyword extends is used in a different context.
In Generics, T extends Something denotes that T will be a sub-class of Something or will implement Something (in the cases of an interface). The type of the bound doesn't really matter (class or interface) - what matters is T to be sub-type of the provided bound.
More info:
Why extends interface instead of implements interface?
I'm trying to declare an object which must implement a specific interface.
I thought the following would work in Java as it does in some other languages but I'm at a loss here:
Class<? implements **theInterface**> implementingObject
Any pointers would be appreciated
for generics, you use "extends" regardless of whether it is a Class or Interface.
Class<? extends **theInterface**> implementingObject
What you are declaring here isn't an object that implements an interface, but a class of an object which implements that interface. An object implementing an interface is simply declared as the interface type, i.e.
theInterface implementingObject;
I want to create a class that takes two parameters. One should be typed simply as T. The other should be typed as something that extends both T and SomeInterface<T>. When I attempt this with
public class SomeClass<T, S extends SomeInterface<T> & T>
then Java complains with
"The type T is not an interface; it cannot be specified as a bounded parameter"
and if instead I attempt to create an interface for S with
public interface TandSomeInterface<T> extends SomeInterface<T>, T
then Java complains with
"Cannot refer to the type parameter T as a supertype"
Is there any way to do this in Java? I think you can do it in C++...?
You can't create an interface that extends the type parameter T since there's no contract that would guarantee T to be an interface. And of course interface extending a class is not allowed.
this works if you extend an interface as well:
public class SomeClass<T extends I, S extends SomeInterface<T> & I>
but maybe it's not exactly what you want ...
I'm upgrading some code to Java 5 and am clearly not understanding something with Generics. I have other classes which implement Comparable once, which I've been able to implement. But now I've got a class which, due to inheritance, ends up trying to implement Comparable for 2 types. Here's my situation:
I've got the following classes/interfaces:
interface Foo extends Comparable<Foo>
interface Bar extends Comparable<Bar>
abstract class BarDescription implements Bar
class FooBar extends BarDescription implements Foo
With this, I get the error 'interface Comparable cannot be implemented more than once with different arguments...'
Why can't I have a compareTo(Foo foo) implemented in FooBar, and also a compareTo(Bar) implemented in BarDescription? Isn't this simply method overloading?
Edit: I have many classes which extend BarDescription. If I remove the type parameter for Comparable on Bar, leaving it in the raw state, then I get a bunch of compiler warnings when sorting all the classes which extend BarDescription. Would this be solved with the wildcards answer below? That answer looks quite complicated and difficult to understand for maintenance.
Generics don't exist after bytecode has been compiled.
Restrictions from this: You can't implement / extend two or more interfaces / classes that would be same without the generic parameter and are different with the generic parameter.
What you could do if you really really want type safety is:
interface Foo<T extends Foo<?>> extends Comparable<T>
interface Bar<T extends Bar<?>> extends Comparable<T>
abstract class BarDescription<T extends Bar<?>> implements Bar<T>
class FooBar extends BarDescription<FooBar> implements Foo<FooBar>
I'd write a couple of Comparators and be done with it.
Having multiple implementations of generic interfaces would run into problems when you consider wildcards.
This does not depend upon erasure.