Is there is any actual difference between these this generic
public class SelfBounded <T extends SelfBounded<T>>{}
and this one
public class SelfBounded <T extends SelfBounded>{}
?
If yes, then how can I observe them?
There are a lot of similar questions here already.
You can read the following article
Or the following questions:
Java Enum definition
Why in java enum is declared as Enum<E extends Enum<E>>
What would be different in Java if Enum declaration didn't have the recursive part
The second one uses a raw type, which should never be used.
But actually neither of these declarations are normally useful. You should almost certainly just use
public class SelfBounded <T>
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).
I am writing some classes using Generics but I can't find a solution
for the class SolutionsSubset and so I a getting the error
"type parameter S is not within its bound". I have read previous
questions about the same error but I can't solve it for my case.
Could anybody help me to improve my knowledge about generics? Any
reference to a good book (I can find in google a lot of information
but if someone can reccommend a book, tutorial, etc. will be welcome).
Although I tried to keep in mind the rules to ask a question but I
apologize if my question doesn't fulfill these rules.
I have the following classes and interfaces:
public interface Subset<T extends Comparable<T>> extends Comparable<Subset<T>>
public class MathSubset<T extends Comparable<T>> extends TreeSet<T> implements Subset<T>
public interface Solution<T extends Comparable<T>>
public interface Solutions<S extends Solution<?>> extends Iterable<S>
public class SolutionsSubset<S extends Solution<?>> extends MathSubset<S> implements Solutions<S>
I need that Subset extends Comparable. In SolutionsSubset, the class MathSubset stores Solution objects. How do I have to change these definition to make it work?
Thanks you in advance
In order to be used as the type argument in MathSubset, SolutionsSubsets S must extend Comparable<S>. As a compilable example:
import java.util.TreeSet;
interface Subset<T extends Comparable<T>>
extends Comparable<Subset<T>> { }
class MathSubset<T extends Comparable<T>>
extends TreeSet<T>
implements Subset<T>
{
public int compareTo(Subset<T> other) { throw new Error(); }
}
interface Solution<T extends Comparable<T>> { }
interface Solutions<S extends Solution<?>> extends Iterable<S> { }
class SolutionsSubset<S extends Solution<?> & Comparable<S>>
extends MathSubset<S>
implements Solutions<S>
{ }
A few comments: This is very abstract example, and so not easy to think about. Laying out the code so you don't need to scroll is good. There's an awful lot of inheritance going on here, perhaps compose rather than, say, extending TreeSet. It's difficult to distinguish between the identifiers Solutions and Solution.
Generics are something that can quickly get out of hand, especially if you try to "be all generic" all at once. Less is more. What always helps me is to start concrete (including the implementation) and then slowly substitute generic parameters in, one parameter and class at a time.
Could anybody help me to improve my knowledge about generics?
http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html
Not a tutorial, but lots of useful info. Its one of those references that you read the parts you can understand, but come back to over and over again in the future as you gain more mastery and more of it begins to make sense.
First of all, here is the full error (which is specific to MathSubset not getting a proper parameter): Bound mismatch: The type S is not a valid substitute for the bounded parameter <T extends Comparable<T>> of the type QifFixer.MathSubset<T>
The problem is that MathSubset expects a <T extends Comparable<T>, but you're giving it a S extends Solution<?> - those types having nothing to do with each other, because a Solution does not inherit or implement Comparable<T>.
If anything, you could try this:
public class SolutionsSubset<S extends Comparable<S>> extends
MathSubset<S> implements Solutions<Solution<S>>;
Unfortunately, this will STILL not work because MathSubset implements Iterable, but so does Solutions.
An easy fix would be for Solutions to not extend Iterable, but it really sounds to me like you're trying to use a more complex approach than you need to. May be a "has-a" instead of "is-a" design might be more beneficial here?
Compiles:
public class SerializableObject<T> implements Serializable
{
public T m_object;
}
Does NOT compile:
public class SerializableObject<T> extends T implements Serializable
{
}
So, I want a generic class to derive from its generic type parameter.
Why?
Let's say I have a Map<K, V> and I simply want to serialize it.
I also don't know ahead which keys I'll have.
How do I do that?
So, I want a generic class to derive from its generic type parameter.
You just can't do that, I'm afraid. There are various technical reasons for this, not least of which is type erasure.
You should look for an alternative solution to your issues - this idea is a dead end.
Nope, your goal is near a Dynamic type, which java does not support.
interface Receiver {
public <T extends HasId> void doSomethingWithList(List<T> list);
}
also,
class SubClass implements HasId {}
but
List<SubClass> list = getList();
receiver.doSomethingWithList(list);
fails to compile, complaining doSomethingWithList is not applicable for the arguments List<SubClass>
Where's my mistake?
It looks fine to me. Can it be that you used the wrong List class (i.e. not java.util.class but java.awt.List) in one of the declarations. Perhaps in the interface. Can you double-check import statements? I've made this mistake myself in the past, and it is valid lead on this case :-)
code compiles fine without any problem.
Like irreputable, my quick implementation of your code compiles and runs just fine. Perhaps this can give you some leads; perhaps the issue has more to do with your implementation in regards to Java's support of generic polymorphism.
It seems that you're using an interface rather than class inheritance, but your question title says List<T extends SuperClass>...
I need to define a generic class, and the type parameter must be an enum. I think it should look something like
public class <T> MyClass<T extends Enum<T>> {
}
But I can't seem to figure out the exact syntax. I should mention that I need a way to refer to the type (within MyClass) that it is instantiated with.
Thanks!
public class MyClass<T extends Enum<T>> { }
While the approved answer looks syntactically correct, what's the scenario for such a declaration? Are you trying to write some class that can operate on any enum-defined type, like java.util.EnumSet or java.util.EnumMap? It's an unusual arrangement, so be sure you really need it in order to meet your requirements.