Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Andreas Leitgeb Newsgroups: comp.lang.java.programmer Subject: Re: class parameter with generic type on a factory Date: Sat, 21 Jan 2017 19:33:20 -0000 (UTC) Organization: A noiseless patient Spider Lines: 36 Message-ID: References: <39e83ab1-6a6a-4211-8f3b-0237d56d4202@googlegroups.com> Reply-To: avl@logic.at Injection-Date: Sat, 21 Jan 2017 19:33:20 -0000 (UTC) Injection-Info: mx02.eternal-september.org; posting-host="db41d961b135c1fc530bfa21e3592a27"; logging-data="26228"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19ENHuK3GMPsPnXH8kJi9Sk" User-Agent: slrn/1.0.2 (Linux) Cancel-Lock: sha1:jl3o3RWlbChuTq6a//SYJ8LkyXk= Xref: csiph.com comp.lang.java.programmer:36204 Philipp Kraus wrote: > I have got an interface > interface MyInterface {} > based on this Interface I have a class > public MyClass implements MyInterface {} > and a factory class which generates MyInterface objects with a Class parameter at the constructor > [...] > If I try to create an object of the factory with > new MyFactor( MyClass.class ); It is important to understand that in Java generics are primarily a compile-time thing. If the compiler can see that all types fit, then it can guarantee that no ClassCastException will possibly surprise you at runtime, (except where you do an explicit cast). Now, if you pass MyClass.class to the factory, there is no way for the *compiler* to know that these instances will consistently have the used factory's type param as their type param. *You* on the other hand *can* tell for sure, that the instances you create will only ever be used with the factory's type parameter, like String. This is the situation, where it is ok to "help" the compiler and tell it that the instance you create (which originally is of type MyClass, and thus only implements MyInterface) can safely be assumed to be always e.g. a MyClass (if String was the used factory's type param). You do this by using the annotation @SuppressWarnings("unchecked") on the method that calls newInstance on the provided constructor and casts(!) the MyClass to MyClass (where T here is the factory's type param). It's then your responsibility that no ref to such an instance will ever be cast to a different type parameter, but that's not likely to happen in your factory method, anyway.