Class and Generic in Java - java

There is this function
Transformers.aliasToBean(RoomInfoDTO.class);
Now I would to use the above function in my generic method. How do I pass the class into the method and use it ?
I tried the following but it doesn't work
passThis(PurchaseHistoryDTO.class);
....
function passThis(Class<?> passedClass){
Transformers.aliasToBean(passedClass.getClass());
}
Somehow the function takes the class as class java.lang.Class.

Just pass the argument directly without calling getClass on it. passedClass is a Class object, so calling getClass on it will obviously return java.lang.Class. Just do:
function passThis(Class<?> passedClass){
Transformers.aliasToBean(passedClass); //just pass the class, not the class's class
}
Also, I'm assuming that "function" is shorthand/psuedocode; that won't compile in java. substitute it with a return type, probably void.

As you already passed class object PurchaseHistoryDTO.class in
Class<?> passedClass argument,
just pass "passedClass in the method like :
Transformers.aliasToBean(passedClass);
It should work.

You're passing in the class, so you can operate on it directly.
void passThis(Class<?> passedClass) {
Transformers.aliasToBean(passedClass);
}
You also don't say function in Java. You might be thinking of JavaScript.
On another note, there is basically no point to using a generic class as you have it in your example. Passing in simply (Class passedClass) would work just as well.
So the question is why you went the generics route. It could be you want something more like this:
<T> T passThis(Class<T> passedClass){
return Transformers.aliasToBean(passedClass);
}
Just depends on what you are trying to accomplish.

Related

Java Anonymous Class with Interface

I didn't write Java for a long time and need some help with something (maybe) simple.
So I got this Class in which an Interface is declared :
public class test(){
interface Checker(){
public check();
}
public someFunction(List param1, Checker param2){
//[do something here]
}
...
public static void main (...){
someFunction(List param1, new Checker(){
...
//[implementation of interface]
...
});
}
So my problem is, that (and the actual Code works fine)
I really don't get why the method someFunction(); expects a Interface as a parameter
I also don't understand why I can pass an instance of an interface to that function(inmain()). The second argument that I'm passing the someFunction();`, is an instance of an interface, right?
Well, what i was thinking of, is that it actually is some kind of anonymous class and therefore it might be possible.
But as I said, it's been a while since I wrote java code, and I didn't find an answer yet, so I would be really grateful if somebody could explain to me why and how this piece of code is working.
1) Because by definition public someFunction(List param1, Checker param2) expects an object of Checker (see parameter 2)
2) Yes, it is an anonymous class, and an instance of it new Checker() creates an object of the class which is passed.
Hence, the code works.
i really dont get, WHY the method someFunction() expects a Interface as parameter
That's a choice of the developer but using an interface here allows you to use any implementation - and only interfaces allow a sort of muliple inheritance in Java.
i also dont understand WHY i can pass an instance of an interface to that function (in main()). The second argument that i'm passing the someFunction(), is an instance of an interface, right? Well, what i was thinking of, is that it actually is some kind of anonymous Class and therefore it might be possible.
The code you see basically creates an anonymous implementation of the interface and instance of that anonymous class. So your guess is correct here.
I'll assume public check() was a typo.
i really dont get, WHY the method someFunction() expects a Interface as parameter
Why not? Your interface is Checker and your method signature is
public someFunction(List param1, Checker param2)
The second argument takes a Checker.
i also dont understand WHY i can pass an instance of an interface to that function (in main()).
You aren't passing an instance of an interface. You are passing an anonymous class. When you say:
new Checker(){
...
//[implementation of interface]
...
});
you are implementing the interface.

Object vs Class<T> (vs Class<?>?) in java?

I'm very new to Java. This is probably a stupid question--but i can't find the answer anywhere. If you wanted to declare a method that would take in an unknown object and do something with it (copy it, for example), what would be the difference between something like:
<T> T func(Class<T> cls){
//do something
}
Object func(Object o){
//do something
}
Are they comparable? Is there anything you could/would do with one of the above methods and not the other? And where does Class<?> fit in?
The difference in your code is that former func receives a Class<T> (which can be Class<?>) which means the method only receives a Class type . The latter receives any object, regardless if it's a class or another kind of object.
From Class javadoc:
Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions.
Note that Class is metadata for your classes.
If your code were like this:
<T> T func(T o){
//do something
}
Object func(Object o){
//do something
}
The main difference is the return type: the former return type should be as the same type of the argument, while the latter is a generic Object. For example:
Object func(Object o){
//do something
return o.toString(); //compiles and works
}
<T> T func(T o){
//do something
return o.toString(); //does not compile
}
Class is a very specialized type of an object. Class<T> is not a replacement for any kind of object, it is rather a class descriptor. In Java, where everything is an object, also classes are objects, so there is this type - Class - which abstracts over the "class" class of objects.
Here's an example:
If you have this:
Class<Object> obj = Object.class;
func(obj);
, this doesn't mean that inside your func method you will have access to an Object instance; you will have access to a Class<Object> instance, which is he descriptor of the Object class.
So, to answer your question, you should use Object for your declared purpose.
Class and Object are 2 different things in Java. If you wanted to take any type of object, which you don't care the type of, the following is more normally seen.
Object func(Object o){
//do something
}
It is more common to declare functions with Object vs Class, since there are a few more steps for passing a class than an object.
lets hava a look at your functions
<T> T func(Class<T> cls){
//do something
}
this one takes class as parameter, and returns instance of the class,
imagine method as black box which do some magic stuff
you enter String.class and you will get "hello world"
second one
Object func(Object o){
//do something
}
takes object as parameter and returns object, so in theory, you can insert class and returns instance, but you can also put date and received String
The first function accepts a java.lang.Class (that is also an instance of an Object class, because Class extends it. You can find more information about the Class class in the javadoc: http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html ).
Hence the first method can do something with an instance of Class and it does not accept all objects (note the capital letter, it is a name of a class).
The second method accepts all objects (because every object extends java.lang.Object). (Object's javadoc: http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html)
So if you want to create a method that may "take in an unknown object and do something with it" you have to use the second method. You should also know that usually you do not need a method that accepts any object or unknown object and you should not create such methods if you can find another solution (because it causes the code to be harder to read).
A method that accepts Class as an argument is useful when you want to do something with the definition of a class (retrieve a list of fields, methods, constructors etc.). This webpage explains how you can use the Class class: http://docs.oracle.com/javase/tutorial/reflect/index.html
Additionally, if you want to learn more about generics you should read this tutorial: http://docs.oracle.com/javase/tutorial/java/generics/

How to call a generic method directly?

Here is the method I am calling:
public static <T extends Something> Group<T> getGroup() { ... }
If I wanted to store the result in a variable, I would do something like this:
Group<SomethingSubClass> group = StaticClass.getGroup();
How would I call the method without storing it in a variable?
StaticClass.getGroup();
The above is what I tried, but I am unsure (mostly don't think it is possible from the way my method is) to add the generic type T.
Solution:
StaticClass.<SomethingSubClass>getGroup();
You don't need anything special. Just invoke it as
StaticClass.getGroup();
You will simply be ignore the return value. The type argument will be inferred as Something, which is what you'd have access to in your method anyway.
You would specify an actual type argument by doing
StaticClass.<SomeTypeThatExtendsSomething>getGroup();
but you don't need that since the only part of your method that makes use of the generic type is the return type, which you are discarding.

Extend a class using generics for a specific type

I am wondering. I have a class OccList<T>. I am fine with OccList holding any object, but I want to do more if T is a String, or if T is an integer.
Is there any way I can use the same name while doing it? My solution thus far is to create a new class class StringOccList extends OccList<String>. Optimally I'd like to be able to use OccList<String> and let java create the appropriate class according to the type used, much like method signatures work. Is it possible? Is there a better solution?
It has to be a different class, unless you want the added functionality to be part of the base class.
Think about it; lets say you have a method printAll that calls System.out.println on all the contents of the list. Where is the method going to go?
You only want the method to be callable if it's a String. Then it cannot be part of the base class (because otherwise it would be defined in the base class), so you need to use a different class like StringOccList
It's okay if the method is callable in the base class. You can write it so that (in the case of String) it calls T.toString on all members, or you can have the method throw an exception if T isn't the appropriate type.
That's what it means to be "generic" - the class will work for any kind of inner type. If it won't work for any kind of inner type, then it's not generic anymore!
Yes, you could make use of the one place where Java infers types, that is method returns. Imagine you want an OccList of String, but you don't want to do this
OccList<String> list = new OccList<String>();
Well, then you just write up a method to do that. Like this:
public static <E> OccList<E> newOccList(){
return new OccList();
}
and invoke it like this:
OccList<String> stringList = newOccList();
OccList<Integer> integerList = newOccList();
OccList<File> fileList = newOccList();
It'll work for any generic type you need.
This is used in the Google Guava library, please refer to it here

Get the same Java Class instance I'm passing through parameter

I'm developing a web-app in Java language, which is composed by a system and some modules. All of them implement the IAppIdentifier interface and I have all the module references and the system itself stored in a List into the system.
The idea is to design that in such way that every module will be able to access the system itself or another modules if they have the required interface (extended from IAppIdentifier), so they have to ask the system for them.
I have this code which works:
#Override
public IAppIdentifier moduleByClass(Class<? extends IAppIdentifier> clazz) {
List<IAppIdentifier> iApps = this.get_Iapps();
for (IAppIdentifier iApp : iApps) {
if (clazz.isAssignableFrom(iApp.getClass())) {
return iApp;
}
}
return null;
}
Basically it's checking that each class from the array is assignable from the required interface and if it is it will return that instance. However the matter is that I have to cast it when it's returned by the method.
For example I have to implement something like that to obtain system's instance:
((ISystem) this.get_Service().moduleByClass(ISystem.class))
My question is, is there any way in java to avoid doing that casting again, ergo, to ensure it will return the same type I'm passing as argument at compile time?
Change method signature to this one :
public <T extends IAppIdenfitier> T moduleByClass(Class<T> clazz)
This should work.
Even if your interface isn't generic you can still use generics in methods for they own purpose. By this code you provide generic rule that T has to be IAppIdentifier itself or has to extend it. Your method now will return object of type T and take as param class as Class<T>.
Then in your code whenever you invoke method moduleByClass you don't have to cast it, for example:
ISystem = this.get_Service().moduleByClass(ISystem.class);
Cast won't be needed here and everything will compile.
There is more info needed according to #XtremeBiker good comment. Inside moduleByClass method it's needed to cast resulting type to T. So it was:
return iApp;
But now it should be:
return clazz.cast(iApp);
Anyway it's still less annoying to make cast in on place inside method body than doing it everytime when that method is invoke.

Categories

Resources