That's right, if you don't type a class reference, then even generic methods that only use method type parameters will not be generified. It's one of the weirder nuances of Java Generics. As you say, you can put in some arbitrary type for T : Data data = new GenericClassFactory().
NewObject(new ClassMatcher(){...}, "key1", "my.package.name. Impl") But more likely this shouldn't even be an instance method. Can't it be a static method?
If so you could just invoke it like this: Data data = GenericClassFactory. NewObject(new ClassMatcher(){...}, "key1", "my.package.name. Impl") Edit Note that this extends to all instance members, not just generic instance methods.
Thus, there are simpler cases that demonstrate this odd nuance. This code compiles with only warnings: public class Scratchpad { List list; public static void main(String args) { Scratchpad sp = new Scratchpad(); List list = sp. List; } } And that's because sp.
List is resolved as a List not a List.
That's right, if you don't type a class reference, then even generic methods that only use method type parameters will not be generified. It's one of the weirder nuances of Java Generics. As you say, you can put in some arbitrary type for T: Data data = new GenericClassFactory().
NewObject(new ClassMatcher(){...}, "key1", "my.package.name. Impl"); But more likely this shouldn't even be an instance method. Can't it be a static method?
If so you could just invoke it like this: Data data = GenericClassFactory. NewObject(new ClassMatcher(){...}, "key1", "my.package.name. Impl"); Edit Note that this extends to all instance members, not just generic instance methods.
Thus, there are simpler cases that demonstrate this odd nuance. This code compiles with only warnings: public class Scratchpad { List list; public static void main(String args) { Scratchpad sp = new Scratchpad(); List list = sp. List; } } And that's because sp.
List is resolved as a List, not a List, even though Scratchpad. List has nothing to do with T. This is verbosely documented in the JLS, Section 4.8: The type of a constructor (§8.8), instance method (§8.8, §9.4), or non-static field (§8.3) M of a raw type C that is not inherited from its superclasses or superinterfaces is the erasure of its type in the generic declaration corresponding to C.
The type of a static member of a raw type C is the same as its type in the generic declaration corresponding to C.
Thanks Mark. I think what I will make it static and go with my last alternative approach and just remove the class generic completely. My concern about it being too broad is because I will more than likely have an interface that inherits the ClassMatchable interface and thus I would need to make sure that the instantiated class is of that type but from Ingo's response below I can cast it this way.
GenericClassFactory. NewObject("key1", "my.package. Impl"); – Nick Apr 20 at 18:18.
Consider if T really is a type parameter of the class or the method. For example, is there something in the class that restricts created types to T (class-level), or perhaps it is being used as a convenience to avoid casting result values (method-level). From what you've posted here, it seems to me that T should be a type on the method and that your last example is the answer.
The method definition doesn't seem too wide, if the class implementation is generic and can give out different types with each method invocation.
You should tell the actual types of E and K when calling the method: new GenericClassFactory(). NewObject(...) It appears that Java can't infer it from the argument. And, of course: Its like it doesn't recognize method generics if you have a Class Generic defined but not used.Is exactly correct.
Thanks Ingo, I was wondering how to do the generic casting for methods. I'll remove the class generic and just use method generics – Nick Apr 20 at 18:20.
Its like it doesn't recognize method generics if you have a Class Generic defined but not used. Exactly right. If you define a generic constraint on a class, and then instantiate the class without providing any generic constraint (that is, you leave off the completely), then you've just stepped into the realm of Raw Types, where nothing is the same anymore.
Raw Types only exist for backwards compatibility. According to Angelika Langer's excellent Java Generics FAQ, The use of raw types in code written after the introduction of genericity into the Java programming language is discouraged. According to the Java Language Specification, it is possible that future versions of the Java programming language will disallow the use of raw types.It also states: Methods or constructors of a raw type have the signature that they would have after type erasure.
A method or constructor call to a raw type generates an unchecked warning if the erasure changes the argument types. If the newObject() method doesn't make use of the type parameter T of the class that it belongs to, then something is wrong with your design: most likely newObject() should be made a static method. However, if it really must be an instance method for some reason, you may be able to get it to work by using the wildcard type GenericClassFactory: GenericClassFactory gcf = new GenericClassFactory(); Data data = gcf.
NewObject(new ClassMatcher(){...}, "key1", "my.package.name. Impl").
You can't use a wildcard in an instantiation. – Mark Peters Apr 20 at 19:01 Other than that it's good, +1. – Mark Peters Apr 20 at 19:08 @Mark: Ah yes, good catch.
I've split the instantiation and use into two lines to show how it could be done. It's still a less-than-optimal solution in any case. – Daniel Pryden Apr 20 at 19:20.
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.