The Artima Developer Community
Sponsored Link

Weblogs Forum
Reflecting generics

26 replies on 2 pages. Most recent reply: Aug 22, 2013 4:53 PM by sathya sayee

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 26 replies on 2 pages [ « | 1 2 ]
Ian Robertson

Posts: 68
Nickname: ianr
Registered: Apr, 2007

Re: Reflecting generics Posted: Nov 1, 2007 4:16 PM
Reply to this message Reply
Advertisement
> It all sounds very nice, but none of it addresses the main problem T.class
I'm not sure what you mean - are you pointing out that the JVM still performs type erasure at runtime, or something else?

> for example the following code still cannot be generic

In what way would you want to take advantage of generics in this code?

bug not

Posts: 16
Nickname: bugmenot2
Registered: May, 2005

Re: Reflecting generics Posted: Jul 27, 2008 3:32 PM
Reply to this message Reply
Hello Ian.

Your post is awesome. It accomplishes exactly what I was trying to do and is very well explained. I, too, wish that type erasure would be removed from java.

I was wondering if we are allowed to use your code?

Namely, I'm working on a mini-framework for designing long-running, persistable and transactional processes modeled as finite state machines and would eventually like to open source it. Your solution would be very useful in my framework.

I couldn't find an email address to contact you at which is why i posted on here.

my email: bpossolo at gmail dot com

Ian Robertson

Posts: 68
Nickname: ianr
Registered: Apr, 2007

Re: Reflecting generics Posted: Aug 21, 2008 6:11 PM
Reply to this message Reply
> I was wondering if we are allowed to use your code?

Absolutely, you may use this code. "Consider it open sourced".

Wouter Coekaerts

Posts: 1
Nickname: coekie
Registered: Jan, 2009

Re: Reflecting generics Posted: Jan 1, 2009 6:05 PM
Reply to this message Reply
The getTypeArguments method posted here is a good start, but to handle all cases (nested classes, type parameter bounds,...) more is needed. That's why (inspired by posts like this one) I wrote a (open source) library to make generic type reflection easier: http://code.google.com/p/gentyref/

The equivalent for getTypeArguments is GenericTypeReflector.getExactSuperType(), which, if the type parameters are known, will return an instance of ParameterizedType (on which you can call getActualTypeArguments()).

Andrew Phillips

Posts: 3
Nickname: demobox
Registered: Sep, 2009

Re: Reflecting generics Posted: Sep 10, 2010 3:38 AM
Reply to this message Reply
More wheel reinvention by me, I guess. *sigh*:

http://blog.xebia.com/2009/03/12/a-general-purpose-utility-to-retrieve-java-generic-type-values/

Ransom Murphy

Posts: 1
Nickname: ransomm
Registered: Jan, 2011

Re: Reflecting generics Posted: Jan 14, 2011 3:55 PM
Reply to this message Reply
Ian,

Is the code you've posted in this blog free for others to use in their own applications? There is a statement at the bottom of the page that you reserve the copyright, and I cannot find any mention of how/if others are licensed to use it.

Thanks,
Ransom

Ian Robertson

Posts: 68
Nickname: ianr
Registered: Apr, 2007

Re: Reflecting generics Posted: Jan 15, 2011 12:06 PM
Reply to this message Reply
> Is the code you've posted in this blog free for others to
> use in their own applications? There is a statement at the
> bottom of the page that you reserve the copyright, and I
> cannot find any mention of how/if others are licensed to
> use it.

I believe the copyright statement is from Artima, not me. Please consider the code open source and feel free to use it!

Remi Morin

Posts: 1
Nickname: remimorin
Registered: Jan, 2011

Re: Reflecting generics Posted: Jan 20, 2011 2:22 PM
Reply to this message Reply
Thanks for that code.

It think Ian know that but me (and I expect for those who will support my code in future) I did'nt figure it out right away.


public class A<T>
{
T woop;
}

public class B extends A<String>
{

}


with this JUnit:

@Test
public void testTypes()
{
final A<String> a1 = new A<String>();//type information not available because not available in class definition (plain definition of A, type undefined).
final A<String> a2 = new A<String>()
{};//type information preserved because included (defined) into annonymous class definition
final A<String> b1 = new B();//preserved because information provided in class definition


final Class<?> a1TypeClass = getTypeArguments(A.class, a1.getClass()).get(0);//null
final Class<?> a2TypeClass = getTypeArguments(A.class, a2.getClass()).get(0);//String
final Class<?> b1TypeClass = getTypeArguments(A.class, b1.getClass()).get(0);//String

assertNull("at run time this is a A instance, no value for parameter", a1TypeClass);
assertNotNull("Ok", a2TypeClass);
assertNotNull("Ok", b1TypeClass);
}


what was not clear to me it's that the class return by any instance is the class definition as found in source code. Not the instance declaration, this information is absent in the reflection universe.

But if parameter are defined in class definition either by explicit inheritance like the case B or by anonymous subclass (a2) then the information will be available.

in my usage of your code I'll add an explicit exception for this:

public static Class<?> getClass(final Type type)
{
if (type instanceof Class) {
return (Class) type;
} else if (type instanceof ParameterizedType) {
return getClass(((ParameterizedType) type).getRawType());
} else if (type instanceof GenericArrayType) {
final Type componentType = ((GenericArrayType) type).getGenericComponentType();
final Class<?> componentClass = getClass(componentType);
if (componentClass != null) {
return Array.newInstance(componentClass, 0).getClass();
} else {
return null;
}
} else {
if (type instanceof TypeVariable<?>) {
throw new InvalidParameterException(
"Error parameter is not define in this class implementation, generic parameter is probably provided at class instanciation, need to be define at class definition (subclassing)");
}
return null;
}
}


To help future developer finding this issue since this 2 little brackets look like a bit weird alone and may get deleted by some cleanup
final A<String> a2 = new A<String>(){};

John Glynn

Posts: 1
Nickname: jglynn43
Registered: Feb, 2011

Re: Reflecting generics Posted: Feb 27, 2011 10:42 AM
Reply to this message Reply
Thanks Ian.

I was working a a small framework built around this interface:

public interface Transformer<T,Y> {
    public Y transform(T t);
}


I wanted to implement a generic arbitrarily long sequence of Transformers with the requirement that the output type of one is the input type of the next. Like:

public abstract class ChainedTransformer<T, Y> implements Transformer<T, Y> {
    private List<Transformer<?, ?>> transformers;
 
    .
    .
    .
 
    public Y transform(T t) {
        Object out = t;
        for (Transformer<?, ?> trans : transformers) {
            out = trans.transform(out);
        }
        return (Y) out;
    }
 
}


I wasn't getting very far until I found your example. I had to make couple of changes in my design*, but everthing works. Now I can chain them together like T->K->V->X->Y and from the outside, it acts like a T->Y. It kind of worked before but there was no guarantee of the types matching. Now I verify that they match up in the ChainedTransformer constructor.

*I had to make the Transformer interface an abstract class with methods to return the actual types for the input and output using your code sample. Also, I had to change the type of the internal list from Transformer<?,?> to Transformer<Object, Object> so I still needed one cast.

Mohan Radhakrishnan

Posts: 1
Nickname: rmohan
Registered: Aug, 2011

Re: Reflecting generics Posted: Aug 5, 2011 5:32 AM
Reply to this message Reply
public abstract class AbstractUserType<T> implements UserType {
...
public Class returnedClass {
ParameterizedType parameterizedType =
(ParameterizedType) getClass().getGenericSuperClass();
return (Class) parameterizedtype.getActualTypeArguments()[0];
}
...
}


I am trying to understand this section of the code. What is special about this section ? Doesn't compile for me.

Artoo Emtoo

Posts: 1
Nickname: r2d2m2
Registered: Jan, 2013

Re: Reflecting generics Posted: Jan 9, 2013 2:18 AM
Reply to this message Reply
> The goal here isn't so much to create a type token as it
> is to adhere to the DRY principal.

Does the DRY principal really apply here? I think not. No matter how many times we refer to SomeType we can use simple refactoring to rename it. And our compiler will certainly let us know if all three mentions of our argument type don't match (so type correctness is assured). The DRY principal does not aim to eliminate multiple instances of SumType.class or Foo<T> any more than it aims to eliminate multiple instances of new Foo(). To suggest that it does would be just plain silly.

And even if it did aim to eliminate all repetition (including multiple instances of i++) should we really be so overzealous in attempting to achieve this goal whilst turning a blind eye to all other considerations?

According to The Java Tutorial (For Beginners)...

"Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications."

Thousands of mobile app developers are hoping and praying that this kind of around-the-world-and-back-code does not find it's way into their class libraries

There may be a time and a place for such heavy use of the Reflection API but getting the argument type at runtime is probably best done the ugly, repetitive, efficient way.

Foo<Bar> barFoo = new Foo<Bar>(Bar.class);

sathya sayee

Posts: 1
Nickname: sathsy
Registered: Aug, 2013

Re: Reflecting generics Posted: Aug 22, 2013 4:53 PM
Reply to this message Reply
Ian,

Stumbled on this post, cleared up some confusion about Erasures for me.

Thanks,
Sathya

PS: Used to work with you in OSTK

Flat View: This topic has 26 replies on 2 pages [ « | 1  2 ]
Topic: Scala, Patterns and The Perl Effect Previous Topic   Next Topic Topic:


Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us