The generic information is lost in runtime. There is no runtime equivalent of a Creator.class. You could create a type between Creator and StringCreator which fixes the generic type: public interface Creator { T create(); } public interface StringCreator extends Creator { } public class StringCreatorImpl implements StringCreator { public String create() { return new String(); } } public class FancyStringCreator implements StringCreator { public String create() { return new StringBuffer().toString(); } } public static void main(String args) throws Exception { Class someClass = Class.
ForName(args0); Class creatorClass = someClass. AsSubclass(StringCreator. Class); Constructor creatorCtor = creatorClass.
GetConstructor((Class) null); Creator creator = creatorCtor. NewInstance((Object) null); } But of course you lose a bit of flexibility, because you cannot use the following creator class: public class AnotherCreator implements Creator { public String create() { return ""; } }.
Not all generic information is lost at runtime; there is enough left to check for the necessary type information even without creating another interface. It's just that there's just not enough info left for the compiler to deduce the correctness. – erickson Dec 10 '08 at 19:48 You're right there.
What I said (in a complicated way) is that there is no class object that represents Creator in difference to Creator. But your code snipped below seems like a reasonable way to solve the problem. – Markus Dec 11 '08 at 17:49.
You don't need that line. Nor do you need the constructor as you're just using the default one. Just instantiate the class directly: public static void main(String args) throws Exception { Class someClass = Class.
ForName(args0); Creator creator = (Creator) someClass.newInstance(); } If you insist, you'll only be able to get halfway there: public static void main(String args) throws Exception { Class someClass = Class. ForName(args0); Class creatorClass = someClass. AsSubclass(Creator.
Class); Constructor creatorCtor = creatorClass. GetConstructor((Class) null); Creator creator = (Creator) creatorCtor. NewInstance((Object) null); }.
Claz.newInstance() and ctor.newInstance() don't behave exactly the same when an error occurs. Class's newInstance method is older, and inconsistent with other reflective "method" invocations. – erickson Dec 10 '08 at 16:33.
This will do what you are trying to do while providing type safety. There's no way to avoid an unchecked warning, but the type checking done here justifies its suppression. Public static void main(String args) throws Exception { Class> clz = load(argv0, String.
Class); Constructor> ctor = clz.getConstructor(); Creator creator = ctor.newInstance(); System.out. Println(creator.create()); } public static Class load(String fqcn, Class type) throws ClassNotFoundException { Class any = Class. ForName(fqcn); for (Class clz = any; clz!
= null; clz = clz.getSuperclass()) { for (Object ifc : clz. GetGenericInterfaces()) { if (ifc instanceof ParameterizedType) { ParameterizedType pType = (ParameterizedType) ifc; if (Creator.class. Equals(pType.getRawType())) { if (!pType.
GetActualTypeArguments()0. Equals(type)) throw new ClassCastException("Class implements " + pType); /* We've done the necessary checks to show that this is safe. */ @SuppressWarnings("unchecked") Class creator = (Class) any; return creator; } } } } throw new ClassCastException(fqcn + " does not implement Creator"); } The main restriction you have to adhere to is that a class in the hierarchy must specify the type parameter.
For example class MyCreator implements Creator. You can't use it with class GenericCreator implements Creator. It doesn't currently handle the valid case where you create a new interface interface StringCreatorIfc extends Creator, and have a class implement that.It could be enhanced to do that, but I'll leave that as an exercise for those inclined.
Not quite sure why you're using generics here. The instantiation of the object using reflection would suggest a general use but presumably you're going to call create at some point and assign the result to a String, otherwise why use the generics to control the return type. But if you wrote the following implementation of Creator: public class IntegerCreator implements Creator { public Integer create() { ... } } And passed it in as a argument you'd get a ClassCastException when calling create and assigning the result.
Edit: I like Marcus' approach as being the most simple and pragmatic without circumventing the whole generics thing. I can use it in my situation because I can specify that the class passed must be a subclass of StringCreator. But as Ericson pointed out the generic information is still there at the type level, just not at the runtime level so it is still possible to reflectively examine whether a given class implements the correct generic type.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.