How can Class<T> be generic? - java

The Java class Class<T> being Generic is confusing because of following reasons.
Imagine a class Cake<T>{}
So you can create
new Cake<Pineapple> and new Cake<Apple> etc
If each class e.x Apple has a parameterizable Class Object, and If class Class is generic, then it seems like a possibility to create Apple<Something> or Integer<Something>, which does not make any sense.
I dont know what i am perceiving wrongly here. It seems like inception, but a deeper level is the same level as above level.
Assume below generic Class
public class Cake<T> {
T cakeType;
void setCakeType(T cakeArg){
this.cakeType = cakeArg;
}
void doStuff(){
System.out.println(cakeType.toString());
}
}
Assume Pineapple is the non generic class as Parameter type for Cake
public class Pineapple {
#Override
public String toString() {
return "I am a Pineapple";
}
}
If class Class was not generic, then by intuition, there will be Pineapple Class object
But as class Class<T> itself is generic. Then it seems like a possibility to create parameterizable class object of Pineapple i.e Pineapple<Something>.
Base Assumption: There is only one Class Object for each class. What is the sense about parameterizing it ?

I'll try to tackle this from a few different approaches; I think there's a fundamental disconnect between what's happening, so a scattershot approach might have a better chance of one of the points making it all "click."
The hierarchy
So, firstly, don't think of Apple as having a Class object; rather, there is an Apple class, and, sitting next to it, a Class object which describes it. But that Class object just exists on its own, and is not part of Apple's hierarchy. It's not Apple's parent; it's its best friend.
The base class for all classes is Object, not Class. Now, if Object were parameterized, you'd have something along the lines of what you're describing -- but it's not. Since Class is not part of Apple's hierarchy, it does not logically follow that Class being parametrized makes Apple parameterized.
By analogy to other generic classes
The point of a Class object is to talk about other objects -- to tell us things like "this is a T," or "here's how you create a T." So, how does each instance tell us at compile-time which kind of things it's talking about? Via the parameter.
Similarly, the point of a List object is to talk about other objects -- to put them into a group together. And it also uses the generic parameter to describe the kinds of things it talks about. With a List, you can tell what's in it just by the type signature: a List<String> concerns Strings while a List<Integer> concerns Integers. Well, in just the same way, a Class<String> talks about Strings while a Class<Integer> talks about Integers. The fact that Class is parameterized has no more effect on String or Integer than does the fact that List is parameterized.
In other words: at the highest level, List<String> does things with Strings. So does a Class<String>
Some use cases
Finally, it may be helpful to think about why Class is parameterized. There are only a few methods on Class that return the T type. Let's take a look at two of them:
T newInstance()
T cast(Object o);
If Class were not parameterized, both of these would return Object. You'd have to do something like this:
Class<Apple> appleClass = ...;
Apple newApple = (Apple) appleClass.newInstance();
Apple existingApple = (Apple) appleClass.cast(existingObject);
Okay, as such that's not too bad. But in this case, we already knew the type of thing we were interested in (an Apple). That's why we could add the Apple casts, but by the same token, it's why using the Class<Apple> isn't useful. That snippet above would be better off just being done as:
Apple newApple = new Apple();
Apple existingApple = (Apple) existingObject;
Instead, the generic aspect of classes are most often useful when you're in a method that is itself generic. For instance:
<T> T tryConsume(Consumer<T> consumer, Object item, Class<T> consumeClass) {
T itemCasted = consumeClass.cast(item);
consumer.consume(itemCasted);
}
Granted, this example isn't very interesting. But the one thing I'll point out is that without the consumeClass, you would have to cast item to (T). Due to type erasure, this would actually be a no-op at runtime, and if the item were of the wrong class, the ClassCastException would come in from a weird, generated line within the consumer code -- not from within tryConsume, where it's nice and clear. To make that cast method actually do the cast, and do it usefully, you need consumeClass.cast(item) to return a T. And to do that, consumeClass has to be of type Class<T>.

Related

How to use a generic class as a parameter and extend the type?

I am attempting to use generics in my project to have a base class that can make use of different types of objects. But I am having trouble when trying to pass these generic typed classes as parameters in some cases.
So I guess my question is, is there any way to use a certain generic typed interface and pass in extensions of the generic type?
I am sorry if I am phrasing this strangely, I am not very used to trying to explain these types of questions. I would be glad for some kind of insight into generics, I feel like I can't get a grip on how they really worked. I have read many posts about them but I couldn't find any that describe my problem or really help me understand it all.
I have tried numerous variations on extending the generic type T, also trying to use wildcards. But I always just end up with way to many nested generics and captures of wildcards and I just make a mess.
I have this interface:
public interface NiceObject<T extends SomeClass> {}
And then I want to be able to extend it with different implementations:
public class EpicClass extends SomeClass {}
public class CoolObject implements NiceObject<EpicClass> {}
This works fine for me, but when I attempt to pass an implementation of NiceObject as a parameter of type NiceObject<T> where T is an extension of SomeClass it tells me that the type is not applicable.
public void coolMethod(NiceObject<SomeClass> obj);
CoolObject obj = new CoolObject();
coolMethod(obj);
// this does not work
I have also tried changing the method in some ways:
public void coolMethod(NiceObject<?> obj);
public void coolMethod(NiceObject<? extends SomeClass> obj);
public <S extends SomeClass> void coolMethod(NiceObject<S> obj);
// None of these produce my desired result
// I just end up with non-applicable parameters somewhere in my program.
EDIT
I'll try to make my question a bit clearer:
NiceObject<EpicClass> obj = new CoolObject();
coolMethod(obj);
// Message:
// The method coolMethod(NiceObject<SomeClass>) in the type NiceMethods
// is not applicable for the arguments (NiceObject<EpicClass>)
What confuses me is that EpicClass is clearly an extension of SomeClass, shouldn't the compiler be able to accept it as a SomeClass because it inherits the same properties as one?
EDIT 2
It seems like I have resolved my issue now. I have a tendency to solve my problem right after I make a post about it.
As a comment proposed, it was more about the problems it caused in other parts of the program. I didn't want to mix in other parts of my program because the structure of it and my overuse of generics is kind of dumb and I did not want to make it even more confusing.
When I modified the coolMethod() to be able to accept any kind of NiceObject<SomeClass> other problems appeared. I had methods in a NiceObject that had to use it's own type of NiceObject as parameters. I solved it by creating a method that would return itself and subtypes would implement that method.
public interface NiceObjectUser <N extends NiceObjectUser<N>> {
public N getSelf();
}
I also did other silly things to make the errors disappear and I had to refactor quite a few other classes. in the end though, it works so whatever.
I do appreciate the answer which explained some things about generics which I have now accepted. I now feel like I have a greater level of understanding of generics.
The issue here is that even though EpicClass is a subtype of SomeClass, NiceObject<EpicClass> is a subtype of NiceObject<SomeClass>. To see why, consider:
class Box<T> {
private T value;
T get() {
return value;
}
void set(T value) {
this.value = value;
}
}
Now think of two classes like Object and String, where String is a subtype of Object. Let's say we allowed Box<String> to be a subtype of Box<Object>. That would mean you can use a Box<String> anywhere that was expecting a Box<Object>. Now think about code like this:
Box<String> stringBox = new Box<String>();
Box<Object> objectBox = stringBox;
objectBox.set(new NonStringObject());
String string = stringBox.get(); // Error! Got a NonStringObject() from a string box!
In general, the fact that a box might consume a T or produce a T means that subtyping rules don't work the way you might expect. In general the proposed alternatives you posted are the way to go when you run into a problem like this; in order to figure out why they're not working we're going to have to know more about the specifics of what you're trying to do.

Java generics - When is ? wildcard needed

Say you have some class with type T:
class MyClass<T extends SomeOtherClass> {
....
}
Now, you want to store instances of this class into a collection, but you don't really care about the type. I would express this as following:
private final List<MyClass> entries = new ArrayList<>();
Is there any good reason/advantage to write the following instead?
private final List<MyClass<?>> entries = new ArrayList<>();
Or even:
private final List<MyClass<? extends SomeOtherClass> entries = new ArrayList<>();
I myself can only find a bad reason to do this: whenever the type definition of MyClass changes (for example addition of another type), you have to alter the List<MyClass<?>> or List<MyClass<? extends SomeOtherClass>> definitions all over your code as well.
update
To update my question:
Why isn't the compiler to be able to track the type(s) of MyClass when your write List<MyClass> (or even List<MyClass<? extends SomeOtherClass>>)? He knows that MyClass is defined as MyClass<T extends SomeOtherClass>, so why isn't he able/allowed to do that when you write List<MyClass>?
In other words, why is List<MyClass> not equal to List<MyClass<?>> (or even List<MyClass<? extends SomeOtherClass>>)? The compiler has all the information to make that conclusion himself, afaik.
The ? wildcard is useful when you don't need to refer to the type again and so you don't need to make a specific identifier.
Your first snippet starts with class MyClass<T extends SomeOtherClass>. This is necessary when T is important later on, perhaps to declare a field argument, or return type. For example:
class MyClass<T extends SomeOtherClass> {
private final List<T> aListOfT;
public T getSomething() {
return this.aListOfT.get(0);
}
Since MyClass is a generic type, all references to it should be qualified to avoid avoidable runtime errors. Thus when you declare List<MyClass> you get a compiler warning that you use the raw type MyClass. If you don't care at that location in the code what sort of type MyClass is qualified with, then you use the ? to tell the compiler that you don't care and let it track the type and check all operations for validity.
Your first declaration means, you are not giving any information about your generic data for the future reflection systems, could be used by plugins, which are written for your main program.
The second declaration tells them, that the field contains an Object generics.
The third one is the more specific, it means, that the reflection systems knows, what is this field about detailly.
Using the first type, java will assume that the generic type is Object. The reason for this is, that generics were introduced in version 1.5. Before then the collection-classes stored everything as an object. For compatibility reasons giving no generic parameter means that you are using object.
The second type simply says you don't know or don't care what type it is. This information is preserved when the code gets compiled. So other programmer who might use your code would know that you don't care.
Because of java's type-erasure, there is no difference between these two at runtime.
With the last form you say:
I don't care what it is, but it has to be SomeOtherClass or a derivated type. Which is the same as:
List<MyClass<SomeOtherClass>>
You can also do it the other way around:
List<MyClass<? super SomeOtherClass>>
says that you don't care what type it is, unless it is a supertype of SomeOtherClass.

Java generics basics

I'm learning programming in java using generic types and got a probably very basic question.
Where's the difference between the further two snippets?
1.)
public void build(House house) {
// work only with house objects that extending House
}
2.)
public <T extends House> void build(T house) {
// work only with house objects that extending House
}
There is no difference between these two methods with respect to what they can take in as parameters; however, in the latter example, one does have access to the specific type T. Regardless, this example does not illustrate the power of generics.
As an example consider a LinkedList of Node<T> objects. We can define a wrapper, Node<T>, which can hold an object of any type. This is a very useful construct, as it allows us to write one piece of code that can be used for many different objects.
The difference is that inside the second function you have access to type type T, the type the caller used to access your method.
I can't think however of any way to use that type that would differ meaningfully from using House directly. It might make a difference with some other parameters or return types of the method.
They are logically the same.
Although, on the second case the compiler can make some advanced verifications.
Let´s say there is are two subclasses of House called XHouse and YHouse.
We have the following source code:
XHouse house = build(yHouse)
This will fail if yHouse is an object of type YHouse and YHouse is not a subclass of XHouse.
Think of a generic as a sort of template. When you fill the generic argument, you sort of create a new method. In the example above, the usage of the generic method is virtually creating the following:
public XHouse void build(XHouse house) {
// work only with XHouse objects that extending XHouse
}
Notice I even changed the comments.

What is the benefit of extending a generic by specifying the new type as actual type of generic

I saw this pattern somewhere:
class A extends B<A> {
}
This structure is a little unusual to extend a generic by specifying the new type as actual type of generic. What is the use? Is there a name for this pattern? Is there any alternative pattern?
Example: https://code.google.com/p/selenium/wiki/LoadableComponent
Jump to: public class EditIssue extends LoadableComponent<EditIssue> {
Edit:
After reading the responses, it seems that I need to alter my understanding of type checking by the compiler. At the back of my mind, my beef with this pattern was, if the two A's need to be same then is there a way to not repeat them? But it seems that there is no better way to propagate the derived class's type to the parent.
Of course the OOP answer is that A is a B. If A were not a B than A should merely compose itself with a B to make use of B's functionality.
Presumably B also has some general implementations which take advantage of restrictions placed on the generic type.
Another use case would be for B to look something like:
abstract class B<T extends B<T>> {
public T createCopy(T t);
}
Now subclasses can implement createCopy and client code can safely use it without having to cast... e.g.
class A extends B<A> {
public A createCopy(A t) {
return new A(t); //copy constructor
}
}
Compare the above to:
abstract class B {
public B createCopy(B t);
}
class A extends B {
public B createCopy(B t) { //Is the copy an A or a different subtype of B? We don't know.
return new A(t); //copy constructor
}
}
You might do something like this when dealing with recursive data structures. For example, nodes in a graph or a tree could be defined as a collection of other nodes:
class Node extends AbstractList<Node> {
...
}
Equally you might see something like this if the abstract/generic type is meant for comparing objects of a similar type, such as is the case with java.lang.Comparable:
class MyObject implements Comparable<MyObject> {
public int compareTo(MyObject other) { ... }
}
Take this example:
E extends Comparable<E>
This means that E must be a type that knows how to compare to itself, hence, the recursive type definition.
Don't know if it has any official names, but I would call it recursive generic type pattern.
It is indeed perplexing, since the two types A and B<A> appear to rely on each other to exist; that doesn't make much sense in ordinary OOP, so what is it for? I found 3 use cases for this pattern.
Composition turned Inheritance
Say a Node has a list of child Nodes. The usual design is through composition
class Node
ArrayList<Node> children = ...
Sometimes for a small performance gain, people use inheritance instead
class Node extends ArrayList<Node>
// the super class represents the children...
This is a little confusing, but there's nothing hard to understand. We know it's just a convenience, it does not try to convey that a node is a list of nodes.
LoadableComponent can be considered of this use case. It's arguably a less ideal design than a composition approach
class ComponentLoader<C>
C get(){...}
class EditIssue
final ComponentLoader<EditIssue> loader = new ComponentLoader<EditIssue>(){
#Override void load(){...}
#Override void isLoaded(){...}
};
EditIssue compo = ...
compo.loader.get().doSomething();
The designer might find this approach more boiler platey.
Method Chaining
Instead of writing
foo.doA();
foo.doB();
a lot of people would rather want to write
foo.doA().doB();
Unfortunately the language doesn't directly support method chaining even though it is becoming an increasingly desired feature. The workaround is for doA() to return foo. It is a little dirty but acceptable.
However if foo is in a type hierarchy the workaround is broken
class Bar
Bar doA()
class Foo extends Bar
Foo doB();
foo.doA().doB(); // doesn't compile, since doA() returns Bar
So some people call for a special "self type" to solve this problem. Let's say there's a keyword This to represent "self type"
class Bar
This doA()
foo.doA().doB(); // works, doA() returns the type of foo, which is Foo
It appears that method chaining is the only use case for "self type", so the language probably will never introduce it (it's better to just support method chaining directly)
People found out that generics provides a workaround for this problem
class Bar<This>
This doA()
class Foo extends Bar<Foo>
Foo has a method "Foo doA()", inherited from Bar<Foo>
This is the most popular use case for the A extends B<A> pattern. It is an isolated workaround/trick. It adds no semantics in relationship between A and B.
It is also a popular practice to constraint This like
class Bar<This extends Bar<This>>
It is ugly and useless, I strongly recommend against it. Simply use "This" as a convention to indicate what it is for.
LoadableComponent can also fall in this use case. In a simpler design we could do
class LoadableComponent
void ensureLoaded()
class EditIssue extends LoadableComponent
EditIssue compo = ...
compo.ensureLoaded();
compo.doSomething();
To support method chaining of the last two lines, LoadableComponent is designed in its current form, so that we can write compo.get().doSomething()
Something more meta
So the previous two use cases are kind of hacks. What if there's a genuine constraint between A and B<A>?
Rather than serving as an ordinary super type, B is more meta, it describes that a type A should have some properties that reference A itself. This is not inheritance in traditional OOP's sense, it is something more abstract. (Though it is still implemented through traditional inheritance mechanism, it's imaginable that the language can promote it as a standalone concept.)
Comparable is of this use case. It describes that a certain type can compare to itself. Since it is not a traditional OOP type, ideally we should never declare an object with static type Comparable. We don't see it in public method return/parameter type, it won't make much sense. Instead we see things like
<T extends Comparable<T>>
void sort(List<T>)
here the method requires a type that conforms to the Comparable pattern.
(I don't really know what I'm talking about in this section)
This pattern is the same as any other sub-class. What's really happening when a generic is used is the JVM is creating a copy (not actually a copy, but it's kinda-sorta like that) of a class, and replacing all the spots where the generic is used with the specified type.
So, to answer your question, all that pattern is doing is substituting B<A> for B in which all the uses of A are substituted with whatever class A is. Potential uses for this are in cases where you are customizing a data structure (from java.util.Collections) for a specific class, such as using bitshifts to compact a Collection<Boolean> into a smaller amount of memory. I hope that makes sense!

Java: How to declare that a variable implements an interface?

In Objective-C, I could do:
id<HTTPRequestDelegate> delegate;
to say that delegate (a variable of type id) conforms to the HTTPRequestDelegate protocol (or implements the HTTPRequestDelegate interface in Java speak).
That way, whenever I send a message defined by the HTTPRequestDelegate protocol to delegate, the compiler understands that delegate responds.
How do I do this, i.e., duck typing / dynamic typing, in Java?
Duck typing doesn't exist in Java. If a class implements an interface, it must declare that this interface is implemented. It isn't sufficient just to have methods with the same signature as the ones in the interface.
An interface is a type, though, and you may declare a variable of this type. For example:
List<String> myList;
declares a variable myList of type List<String>, where List is an interface.
You may initialize this variable with any object implementing this List interface:
myList = new ArrayList<String>();
But then ArrayList must declare that it implements the List interface (which it does).
//Static typing
HTTPRequestDelegate delegate;
Interface a = new Implementation();
Java has no concept of duck typing. You must cast the instance to a known type.
I'm assuming then that delegate doesn't explicitly implement the interface you want.
You could make a new class that implements the interface and extends the implementing class you want (or has the implementing class and explicitly calls the appropriate method in the interface).
If this isn't what you want, you might be in for a healthy dose of reflection. Take a look at java.lang.reflect.Proxy and InvocationHandler.
If you are looking for a shorthand to avoid explicitly implementing methods for an interface using composition, Java doesn't really provide syntactic support for this. You'll have to be explicit.
If you do want to go the reflection-heavy way (not recommended over extra typing), take a look at Mockito.
Most of the answers given already are correct. If an object implements an interface, then you can use that object anywhere an implementation of that interface is needed. This is the most natural approach given Java's strong typing system.
To keep with the example of List/ArrayList, you can create an ArrayList object and then use it anywhere a List is required -- or, based on the other implemented interfaces, Serializable, Cloneable, Iterable, Collection, or RandomAccess. Considering superclasses, an instance of ArrayList can be used as an AbstractList, AbstractCollection, or a java.lang.Object.
Reflection can be used, along with dynamic proxy objects, to wedge an object with the correct methods into a duck costume. That shifts the type checking to runtime, and there are usually far better reasons to work with the normal typing system than against it.
Because it sounded like fun, here an example of wrapping a non-Duck in a proxy object.
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DuckDemo {
public static Duck getDuckProxy(final Object duckLike) {
final InvocationHandler invocationHandler = new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Class<?> actualClass = duckLike.getClass();
String methodName = method.getName();
Class[] parameterTypes = method.getParameterTypes();
Method requested = actualClass.getDeclaredMethod (methodName, parameterTypes);
return requested.invoke(duckLike, args);
}
};
final ClassLoader originalObjectClassLoader = duckLike.getClass().getClassLoader();
Duck woodenDuck = (Duck) Proxy.newProxyInstance(
originalObjectClassLoader,
new Class[] { Duck.class },
invocationHandler
);
return woodenDuck;
}
private interface Duck {
void quack();
};
public static void makeItQuack (Duck duck) {
duck.quack();
}
public static void main (String args[]) {
Object quacksLikeADuck = new Object() {
void quack() {
System.out.println ("Quack!");
}
};
// Does not compile -- makeItQuack(DuckDemo.Duck) [...] cannot be applied to (java.lang.Object)
// makeItQuack (quacksLikeADuck);
// Runtime java.lang.ClassCastException: [...] cannot be cast to GenericProxyFactory$Duck
// makeItQuack ((Duck)quacksLikeADuck);
Duck d = getDuckProxy(quacksLikeADuck);
makeItQuack (d);
}
}
For what it's worth, IBM developerWorks also has a good article on the topic of dynamic proxies.
In Objective-C, the type consists of two parts: 1) An class pointer type (e.g. NSObject *, NSString *, etc); this could also be id, which is a special type that can accept any object pointer and disables static type compiler warnings for calling methods; and 2) optionally, one or more protocols (which are like interfaces in Java) that the object conforms to (e.g. <NSCopying, NSCoding>)
In Java, a reference type is either a class or interface name. (You can only pick one.) There is not so much separation between classes and interfaces.
In your case, your object pointer type is id, which expresses no information, and you specified one interface, HTTPRequestDelegate. This can be equivalently expressed in Java as
HTTPRequestDelegate delegate;
If you had specified more than one protocol, or you specified an actual class pointer type plus one or more protocols, then your type is an "intersection type", the intersection of the multiple types you specified. In that case, it would be harder because there is no simple way of expressing intersection types in Java. (Although intersection types can be specified in generic type bounds, e.g. class Foo<T extends Collection & Comparable & CharSequence>)
Other than that, the only other difference between Objective-C and Java is that in Objective-C, you can send any message (i.e. call any method) on an object pointer and it is allowed, even if the static type of the variable does not indicate that it is supported (the compiler will give a warning if you use an actual class pointer type; if you use id it will not give a warning). I guess this is the dynamic typing you're talking about. Whereas in Java, you can only call methods that are known to be supported by the static type at compile time.
But if you're using a type like id<HTTPRequestDelegate>, then chances are that you only intend to use the methods provided by HTTPRequestDelegate anyway, so you are not using any of the dynamic typing abilities. So in Java just HTTPRequestDelegate will suffice.
I think there's a lot of terminology to unpack here. Java doesn't let you have a raw pointer, only a reference, which has a type.
Anyway, say you have a reference to an instance that you know implements HTTPRequestDelegate. You can cast it, like so:
HTTPRequestDelegate delegate = (HTTPRequestDelegate) ref;
The bit in the parentheses is the cast. You can now call methods on delegate (pass messages in java speak) to your hearts content as long as they are defined on HTTPRequestDelegate.
The other way Java programmers do duck typing type stuff is refection, but if you know the interface, casing is the way to go.

Categories