What is the point of making a class generic? - java

when you have a method, I understand that it makes sense to declare it generic so that i can take generic arguments. Like this:
public <T> void function(T element) {
// Some code...
}
But what exactly is the idea behind making a whole class generic if I can simply declare every method generic?

Well, the difference is if you try to make each method in your class generic the generic type you'd use in your say firstGenericMethod may or may not be the same type.What i mean is.
public <T> void firstGenMethod(...){
}
public <T> void secondGenMethod(...){
}
Test:
SomeClass ref = new SomeClass();
ref.firstGenMethod("string");
ref.secondGenMethod(123);//legal as this generic type is not related to the generic type which is used by firstGenMethod
In the above case there is no gaurentee that both the methods have the same generic type.It depends on how you invoke them. If you make the class generic though, the type is applied to all the methods inside that class.
class Test<T>{
public void firstGenMethod(T t){
}
public void secondGenMethod(T t){
}
}
Test:
Test<String> testingString = new Test<>();
testingString.firstGenMethod("abc");
testingString.firstGenMethod(123);// invalid as your Test class only expects String in this case
You'd usually make your class generic where you'd want the entire behaviour(methods) of that class to process on the same type. best examples are class's in Java Collection Framework

Have a look at the Collection classes. Take List<T> as an example. If the class weren't declared generic, how would you make sure that only elements of the correct class could be inserted into the list? And how would you know what you get when calling ArrayList.get(i)?

Precisely, to enfore that all the methods in this class apply to a certain type.
This is typically used in "containers" classes. If you're building a List, and you make it generic, you want to be sure that adding element, getting element, iterating, etc... always uses the same type.
As you mention, this also allows you to use instance variables of a certain type, and have several methods use this instance (maybe returning it, affect it...) in a coherent way.
If you have a class that is "generic" with several different types, it might be a sign that you're really writing two generic classes in one... (although this can be a legitimate thing.)

The main idea is to bound the class/method for a type.The best example is the concept of Generics in programming language.It is the real application of polymorphism
Generic classes encapsulate operations that are not specific to a particular data type. The most common use for generic classes is with collections like linked lists, hash tables, stacks, queues, trees and so on where operations such as adding and removing items from the collection are performed in much the same way regardless of the type of data being stored.
For most scenarios requiring collection classes, the recommended approach is to use the ones provided in the programming languages.
Reffering from oracle docs
A generic type is a generic class or interface that is parameterized over types
public class Box {
private Object object;
public void set(Object object) { this.object = object; }
public Object get() { return object; }
}
By generically you can strict it to
public class Box<T> {
// T stands for "Type"
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
I also suggest you to see this tutorial

Related

Generics in loop, trying to avoid a cast

I have a method call in a loop currently that does not compile:
for (Example example : Util.getExample(List.class)) {
// Do something with example
}
Util:
public class Util {
public <T> T getExample(Class<T> clazz) {
//...
}
}
The obvious fix is to cast the return from getExample to List<Example>. I'm wondering: is there is an alternative way to avoid the cast?
Further Information:
Posters asked for more information, so here goes...
I have built a framework around annotation processing that writes code to access and mutate class members (constructors, fields and methods). This framework backs both Parceler and Transfuse and allows me to, during compilation, identify a property and generate code to access or modify said property. For private properties (private constructors, private fields, private methods) I use a utility to perform these actions (Parceler's, Transfuse's) to break encapsulation via reflection.
Parceler has a feature to unroll collections during serialization in order to serialize members of the given collection. For private collections the InjectionUtil is used to access these properties within a loop:
for (Example example : InjectionUtil.getField(List.class, Container.class, container, "exampleField")) {
// ...
}
Which is the bug I'm currently faced with, and thus, why I'm asking about avoiding a cast. I'd prefer to not cast as I'd like to generically generate a bit of code to access a type and respect Java generics in the process.
If your getExample method is supposed to always return a list, then yes, change its return type to List<T>. But since you're passing List.class as an argument, it looks like you want to have a method that can return both lists and non-lists depending on which class object you pass it.
If so, that's not going to work the way you might be hoping. Your method in this case returns just List, the raw type. To make it return List<Example>, you'd have to pass it something like a hypothetical List<Example>.class, but there's no such thing. Generic type parameters are erased at compile time, so List<Example> and List<String> are really both the same class; they don't have separate class objects, so a class object argument can't tell your method what kind of list it should return.
You'll probably need to try a different design approach. Since this is clearly a simplified example, you might be able to get more help if you post more details about what you're actually trying to accomplish.
Guava's TypeToken can be used in this case because List<Foo>.class is not valid. TypeToken is used by creating an anonymous class. Because anonymous classes keep their generic signatures, this works.
for (Example foo : Util.getExample(new TypeToken<List<Example>>() {}) {
// do stuff
}
// utils
public <T> T getExample(TypeToken<T> typeToken) {
Type type = typeToken.getType();
// get example
}
TypeToken is more specific than just using the Class. You could also use the plain Type as a parameter so you can still feed it a Class. This is how Gson does it.
I think this is a design issue...
Since the method in Util you are calling is called getExamples it seems reasonable that it might just as well be fixed to return some collectionwhose elements are instance of the Example class.
It is reasonable to change getExamples to something like this?:
class Util {
public static <C extends Collection<? supper Example>> getExamples(final Supplier<C> factory) {
final C result = factory.get();
// here goes the code that adds the examples to the result collection
// using add or addAll.
return result;
}
}
So for-example if you wan to get a List<Example> using ArrayList<E> for implementation you would do like so:
List<Example> examples = Util.getExamples(ArrayList<Example>::new);
Try to pass the returned collection class object reference instead (eg. List.class, ArrayList.class) won't work as the code in getExamples will have a hard time (a) figuring out how to call the appropriate constructor using reflexion to instantiate the result (kinda of impossible if you pass just an interface class object such as List.class) and (b) casting the return from a raw type into a generic type with Example as element type. The latter is trivial however it is not as neat as it can be as it will generate a warning.
It is just more straight forward to delegate in the using code to indicate explicitly how to instantiate the result collection.
If you break away from returning a Collection and use methods like add and addAll in getExamples then perhaps you should borrow the Collectors framework from the java stream API.

How to create instance object of a class that contains a generic type (using reflection)?

Using reflection, I need to create instance object of a class that contains a generic type.
To date, I'm struggling to find a solution.
I thank who can help me.
Example:
Class one:
package app;
public class PTRow {
}
Class two:
package app;
public class PTQuery<T extends PTRow> {
}
Class three. Here the problem:
package app;
public class PTConnection {
public PTQuery<? extends PTRow> createQuery() {
//TODO How implement this?
return null;
}
}
It's possible?
No it isn't.
All generic types are converted to java.lang.Object upon compilation by a process called type erasure. So your nice strongly typed generics are all lost at runtime.
You'll need to use good old-fashioned polymorphism and factory pattern idioms.
First note: using wildcard in generic type parameters is not good practice for method return types. You can of course use wildcards for parameter types.
Coming to your question: the return type you have declared makes it difficult to know what dynamic type to generate, if not for the type PTQuery.
As this is runtime, you could make the method generic, take in the class that is to be used as generic parameter:
public <T extends PTRow> PTQuery<T> createQuery(Class<T> ptRowType){
//And in here, all should be intuitive if you know your types...
}

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.

Access class name of parameterized type

I have a parameterized class. I would like to get the name of the class represented by the class name. For instance, what I want to do is this:
public T foo(){
System.out.println(T.class.getName());
}
You can't do it this way, since T isn't known at compile time. You could achieve something similar like so:
public void foo(T t) {
System.out.println(t.getClass().getName());
}
Note that this takes an instance of T and would print out the name of its dynamic type.
Whether or not this is a good enough substitute depends on your use case.
Java generics don't work that way. If you have any bounds on T, you can access the bounds by querying the type variable definition. E.g.:
public class Foo<T extends Bar>{}
will let you get at Bar, but not at the subtype of Bar you are actually using. It doesn't work, sorry.
Read the Java Generics FAQ for more info.
BTW: One common solution to this problem is to pass the subtype of T into your class, e.g.
public T foo(Class<? extends T> tType){
System.out.println(tType.getName());
}
I know it's cumbersome, but it's all Java generics allow.
public T foo(T t){
System.out.println(t.getClass().getName());
}

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