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 20:11:53 -0000 (UTC) Organization: A noiseless patient Spider Lines: 59 Message-ID: References: <39e83ab1-6a6a-4211-8f3b-0237d56d4202@googlegroups.com> <7049a3a0-7c09-41fa-97c0-82d54b06061e@googlegroups.com> Reply-To: avl@logic.at Injection-Date: Sat, 21 Jan 2017 20:11:53 -0000 (UTC) Injection-Info: mx02.eternal-september.org; posting-host="db41d961b135c1fc530bfa21e3592a27"; logging-data="26228"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX190UyGUiSCToOmXSoUZ6SJc" User-Agent: slrn/1.0.2 (Linux) Cancel-Lock: sha1:z4WJqSCp8dnmrx8IjG9ECOBW9+I= Xref: csiph.com comp.lang.java.programmer:36207 Philipp Kraus wrote: > Am Samstag, 21. Januar 2017 20:35:07 UTC+1 schrieb Andreas Leitgeb: >> 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. > > Thanks for your answer, I know that generic (or in C++ templates) are > only exist on compile-time, but not on runtime. You know partially wrong. It is true for Java, but C++ templates are different. Unlike Java, C++ does know the type parameters at runtime: it even creates a copy of the template code for each parameterization (with some gory exceptions that I don't want to go deeper into, here). > But the questian is, is there a possibility to pass the template > argument to the class object. I'm working with Java 8. Maybe my previous answer was "tl;dr", but it was meant to clarify: "no". > For the compiler I need not a MyClass.class, but I need a > MyClass.class object, but if this is not possible > can I do it without a type-cast? No, you cannot specify MyClass.class - Yes, you need to cast, and yes, you can squelsh the generics-cast-warning, and you need not even feel bad about it for this particular "class-factory" usecase.