How can I use a Dynamically created class as Generics? - java

My problem is I do have a class that is created, compiled and initialized at runtime. I did this as writing the file as TestClass which is File f,
then compile with:
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null,null,null,f.getPath());
After that I load my class and use my methods etc. according to this example;
http://viralpatel.net/blogs/java-dynamic-class-loading-java-reflection-api/
Now my problem is I need to do this:
MyTask<T> m = new MyTask<T>(0,0,0);
T should be my dynamically created class instead of Integer.class etc. However I couldn't find a way for it yet. If you do examine the example at the link I gave above, you will see I can have a instance of my class as in Object form and I can a Class instance for my dynamic class. However, whatever I tried I couldn't find the solution for this.
It keeps saying that Class myClass, can not be used as a type. So how can I use this dynamically created class as a type. Thank you very much.

There is no useful way to express in source code a type that does not exist at compile time. It would not anyway gain you anything more than using Object as a type parameter could do, because Java generics provide compile-time type checking, not run-time type checking.
It might be that your purposes could be served by creating an interface that your dynamic class will implement, and using the interface type as your type parameter.

You can't due to the fact that the generic type information is available only at compile time. When you create a class at runtime, there's no generic information available anywhere any more.
If your class implements an interface, you should use that as the type in code. Something along the lines of
MyInterface foo = myDynamicClass.newInstance();
someGenericMethod(foo);
public <T extends MyInterface> void someGenericMethod(T param) {}
// Or more likely, if there's no other classes that extend MyInterface
public void someGenericMethod(MyInterface param) {}
Of course it may not make any sense to even bother with generic type information, since it's used for static type checking and you're working with a dynamic class.

Related

Java Method Argument Type to be from any type that contains method name

Is there a way to implement in Java Generics method
that the type is any type that has specific function name (not in inheritance ) ?
If I understand your question correctly, it looks like you are trying to use generics to only allow for types that implement a method with a certain name. They're called methods, not functions, in Java.
Unfortunately, this isn't possible directly. The best thing you can do is create an interface that contains the required method, have your classes containing the method implement it, and then use a generic type constraint for that specific interface type:
public interface SomeInterface {
int doSomething(int x, int y);
}
Do note that this requires that the entire signature be the same (not only the same name, but also the same parameters and a compatible return type). Your code would then look like this:
public class GenericClass<T extends SomeInterface> {
Also note that this will only work perfectly if all the classes you're using were made by you. If you're also using classes by someone else that have the same method signature, it should be possible to make your own class that extends the library class and is declared as implementing the interface, and use that class instead of the library class.
If you really need to check for methods that have the same name but not the same signature, there may be another way to do it using reflection. If you need that, please let me know in a comment.

Why is it useful to pass a class to a method in Java?

This hasn't been covered in my course and I am having trouble thinking up a reason why would I want this. I've come across the code below:
OpenNetworking proxy = service.getPort(OpenNetworking.class);
In the above line I can see that it is returning the port and it is passing the class to the method but I read this as the OpenNetworking.class isn't instantiated yet. I'm obviously missing something.
This is an example of a Factory method pattern.
The class type is provided to the service to give a Port on the specified type OpenNetworking.
A class type, in this case, is handy as it is a simplest way to provide a unique identifier to an object when doing object creation. It doesn't need to be maintained, should the state of the object changes as the class contains the type of the object.
There can be many reasons to do that:
Controlling number of instances of a class: Say you want to control how many instances you want for a class, you can make constructor
private or package level and return same instance when somebody calls
your method
Security: You might want your class to be secure and generally don't want to allow anybody to instantiate your class.
Dependency: Your class might have dependency which can be figured out only at runtime and then service class use reflection to
instantiate class appropriately.
Here we are passing the class type (Class in Java). So the treatment in the method getPort is done based on the Type of Class, we don't need an Object instance to handle it.
It is different, of course, than this code (whic doesn't compile):
OpenNetworking proxy = service.getPort(new OpenNetworking());
Also because of limitations of generics, when you have a generic class/method and you need to create a new instance, you will need a class. For example:
class SomeClass<T> {
public static<T> T create() {
return new T(); // will not work
}
public static<T> T create(Class<T> clazz) {
return clazz.newInstance(); //will work
}
}
so you need class instance to create a new object of that type.
Apparently the method service.getPort(); behaves according to the type in the parameter, imagin that there is a port for openNetworking and another one for closeNetworking, so providing the class name as a parameter would be enough to get the needed port number, one can create an enumeration for that but then extending existing code would force you to extend your enumeration too for each type.
The used method has this definition:
public <T> T getPort(Class<T> serviceEndpointInterface)
So it returns an instance of an object which extends the class T (a proxy,synthetic class instance)

Get class object from generic type

I want to simplify a project by removing useless classes. By useless classes I mean something like :
public class MainPage extends TileGridFragment<MainModel> {}
The whole logic of this class is implemented by TileGridFragment, and the data is provided by MainModel, which instance is accessed thanks to a singleton class.
I want to defer the instanciation of such class to a later time, so I simply pass MainPage.class to my methods.
As MainPage is equivalent to TileGridFragment<MainModel>, I would like to remove this class and instead use something like TileGridFragment<MainModel>.class instead.
But this doesn't work and I'm out of idead.
I've also tried Class.forName, but its throws a ClassNotFoundException.
Any idea ?
If the implementation of MainPage is actually {}, just pass TileGridFragment.class. The actual type parameters are irrelevant on runtime because they are removed by erasure.
Also, because of erasure, you can cast the new TileGridFragment (with a raw type, as the result of TitleGridFragment.class.newInstance()) to TitleGridFragment<MainModel>, and ther will be no collateral damages (other than a little warning from the compiler, that can be supressed).
You can't really, you might get some joy from reflection but I'm not sure exactly what you're trying to do.
Try here:
Get generic type of class at runtime

Subclassing a dynamically loaded class in Java

Assume I obtained a Class object by loading a class dynamically using Class.forName("Foo"). Foo is abstract in this case, so I cannot call newInstance() on it. (How) is it possible to declare a concrete subclass of Foo?
You declare it as not abstract e.g.
class Bar extends Foo {
// implement methods are required.
}
In short, just because you loaded the class dynamically doesn't mean the rules change ;)
Foo is not available at compile-time
If you don't have Foo available at compile time, you still need to have a sub-class of this class which is concrete to create it. To do this you have two options.
find a concrete class and create that. You can use the Reflections library to find such a class.
generate code and compile it using the Compiler API, or BeanShell.
generate byte code for the subclass using ObjectWeb's ASM.
I suspect the first option is what you need because unless there is a subclass provided for you, you still need to generate the code for the abstract methods.

How to get the <?> value for a Foo<?> object?

(This is somewhat a followup to my previous question)
I've got a Foo<?> object, foo. Foo<T> is an interface.
How to get the type value hidden behind the <?>?
Note that this is not trivial, as foo can be for example an object of class Bar<String>, where Bar<T> implements Foo<T>, or some anonyomus class implementing interface FloatFoo, where FloatFoo extends Foo<Float>. I need a solution that works in all cases.
Thanks in advance :)
This is not possible using reflection because Java Generics has the problem of Type Erasure. At runtime the types that have been defined for the generic class Foo have been removed, so using reflection on that class will not yield its generic type. This type information is used only in compilation for type safety.
C# does not have this issue and it is possible to access the templatized type of a Class.
This is a overview of the differences.
Well, for short, you can't.
However, what you can do is get the value of <?> when using FloatFoo.
Indeed, from what I remember, generics are not kept in class information.
however, when you create a subtype (be it class or interface) of a generics type, the generics information has to be memorized as it may define some of the subtype's methods signature.
As an example, if your Foo interfaceis declared as it :
public interface Foo<T> {
public T doIt();
}
Having a
public interface FloatFoo extends Foo<Float>
implies this interface has a
public Float doIt();
method declared.
For that, the compiler has to have the type information. And this information will be reflected in the reflection API by the fact that FloatFoo's super class will have some Type parameters associated to it. Or it least it is what I remember from the few cases I encountered such cases (or elaborated them, as it may sometimes be mandatory)
But you'll have far more complete informations at Angelika's generics FAQ.
The final-final (and perhaps the best possible) solution: I refactored my code, so it doesn't need this. I moved all code which needed the type parameter into Foo, so I could provide appropriate implementation within the class. It turned out to be much less code.
I ended up with creating a getType() method in the interface:
Class<T> getType();
Maybe it's not the most elegant solution, but definitely the simplest one.

Categories