I'm creating an interface of JOOQ TableRecord
<R extends TableRecord<R>>
Would anyone be able to explain the line above?
Thanks
It means a class of type R, that implements the interface TableRecord<R>
TableRecord<R> means that the interface is bound to the same type R.
An example would be a class like:
public class Bla implements TableRecord<Bla>
I admit this seems a bit strange, but Java generics don't really differentiate between extends and implements, which leads to some confusion.
As to why this exact definition, I don't know enough about the context to see exactly why it makes sense, but it might be due to method signatures on the interface returning objects of type R (think Factory):
public R createTableRecord(...);
class SomeClass<R extends TableRecord<R>>
What it means that parameter type R has to be a subclass of TableRecord <R> and nothing else, i.e. you must use class
class Foo extends TableRecord <Foo>
as the parameter for defining your class SomeClass
Related
I want to have a Class object, but I want to force whatever class it represents to extend class A and implement interface B.
I can do:
Class<? extends ClassA>
Or:
Class<? extends InterfaceB>
but I can't do both. Is there a way to do this?
Actually, you can do what you want. If you want to provide multiple interfaces or a class plus interfaces, you have to have your wildcard look something like this:
<T extends ClassA & InterfaceB>
See the Generics Tutorial at sun.com, specifically the Bounded Type Parameters section, at the bottom of the page. You can actually list more than one interface if you wish, using & InterfaceName for each one that you need.
This can get arbitrarily complicated. To demonstrate, see the JavaDoc declaration of Collections#max, which (wrapped onto two lines) is:
public static <T extends Object & Comparable<? super T>> T
max(Collection<? extends T> coll)
why so complicated? As said in the Java Generics FAQ: To preserve binary compatibility.
It looks like this doesn't work for variable declaration, but it does work when putting a generic boundary on a class. Thus, to do what you want, you may have to jump through a few hoops. But you can do it. You can do something like this, putting a generic boundary on your class and then:
class classB { }
interface interfaceC { }
public class MyClass<T extends classB & interfaceC> {
Class<T> variable;
}
to get variable that has the restriction that you want. For more information and examples, check out page 3 of Generics in Java 5.0. Note, in <T extends B & C>, the class name must come first, and interfaces follow. And of course you can only list a single class.
You can't do it with "anonymous" type parameters (ie, wildcards that use ?), but you can do it with "named" type parameters. Simply declare the type parameter at method or class level.
import java.util.List;
interface A{}
interface B{}
public class Test<E extends B & A, T extends List<E>> {
T t;
}
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've seen examples of how to declare a generic class whose type parameter is constrained, e.g. it must extend Comparable. I also know how to define an interface for a generic class whose type is similarly constrained. However, when I do the latter, I'm unable to figure out the syntax for the class signature. So, to cut a long story short, if the interface is
public interface iMyClass<T extends Comparable<T>>
what should be the syntax for the signature for the implementing class
public class MyClass.......
Thanks in advance,
D
Do you intend MyClass to be generic as well? If so,
public class MyClass<? extends Comparable<T>> implements iMyClass<T> {
Otherwise, keep things simple and
public class MyClass implements iMyClass<String> {
Replace String with your Comparable.
A constrained type argument is supplied in exactly the same way as a non-constrained one, for instance:
public class MyClass implements iMyClass<String> {
E.g. I have:
interface Consumer<F extends FoodType>
interface Vegetarian extends Consumer<Grass>
interface Predator extends Consumer<Meat>
I want to have something like:
class Feeder<C extends Consumer<F>>
to use F type parameter within Feeder class declaration. The aim is to pass only informative type parameter and to take up other type parameters from the passed ones:
new Feeder<Vegetarian>().buyFood(bluegrassIsGrassAndCouldNotBeMeat)
If the class is going to use two generic types it's going to need two generic parameters even if they are dependent.
class Feeder<C extends Consumer<F>, F extends FoodType>{}
If may be useful to be a bit more flexible.
class Feeder<C extends Consumer<? super F>, F extends FoodType>{}
(Josh Bloch's uses the acronym PECS: Producer's extend; Consumer's super.)
You can use:
class Feeder<C extends Consumer<? extends FoodType>>
or simply:
class Feeder<C extends Consumer<?>>
but there is a difference between them. As far as I understood from your question (it's not very clear) you want one of these two.
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 ...