Obtaining Generics type parameters using reflection

I have been trying to obtain the type parameters of a method using reflection. This is what I have done:
getGenericTypeParameters(aMethod.getTypeParameters());
private static String getGenericTypeParameters(TypeVariable genericParameters[])
       String returnName = new String();
               if(genericParameters.length > 0)
                       returnName += "< ";
                       for(int i=0; i<genericParameters.length; i++)
                               if(i > 0) returnName += ", ";
                               returnName += genericParameters.getName();
returnName += " >";
return returnName;
} This doesn't take care of the cases when the method is of the form  public static <T, V extends T> boolean isIn(T x, V[] y)
and the type parameters I get using the method I've written is <T, V>
Is there any workaround or a better way of doing it?                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

Have you consulted Angelika Langer's [Java Generics FAQs|http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html]?

Similar Messages

  • Eliminating type parameters used only for superclass information?

    I have a class called BaseObject. I have another class called Reference. A
    BaseObject has one canonical Reference that can be gotten and set. A Reference
    is capable of pointing at a BaseObject subclass of a particular type and can
    return the Class of that BaseObject subclass.
    I'd like to genericize these classes so that if you create a reference and
    assign it to an object, their types should line up. That is, a Reference that
    points to a Banana should not be able to be assigned as a canonical reference to
    a Cherry.
    My goal is to express these type constraints once somewhere. I cannot seem to
    achieve my goal.
    Pass one, which looks OK at the outset:
      public class BaseObject<T extends BaseObject> {
        public Reference<T> getReference() {
        public void setReference(final Reference<T> reference) {
      public class Reference<T extends BaseObject> {
        public Class<T> getObjectType() {
      }But that would mean that every subclass of BaseObject<T> would need to be
    declared with a type parameter as well to permit further subclassing, right?
    Like so:
      public class Fruit<T extends Fruit> extends BaseObject<T> {
        // Note: T is not used in this class except to "pass it up" to BaseObject
      public class Banana<T extends Banana> extends Fruit<T> {
        // Note: T is not used in this class except to "pass it up" to Fruit
        // Callers will have to say: new Banana<Banana>();
      }That seems WEIRD to me. Is there any way to...to...hide the genericization of
    the fundamental classes--BaseObject and Reference--without forcing the type
    parameters to be propagated all the way down the subclass stack?
    In other words, assuming a hierarchy of Object<--Fruit<--Banana, is there any
    way to have Fruit and Banana not mention type parameters at all?
    Thanks,
    Laird

    I'm up a creek here, aren't I?I think so. It's been a while since I complained
    about the lack of 'self-types' in Java. 'Self-type'
    actually means something different in other languages
    (Scala for example) so just be aware of that.AH! Yes! That's exactly what I'm talking about. OK, knowing that I'm screwed helps a lot, actually. It lets me know where I can and cannot apply generics to solve problems.
    I would envision:
    class BaseObject<self>
    // OR
    class BaseObject<T extends self>The idea would be that self is what ever the
    'current' class is. So if you used the first one,
    the type of the class that extended BaseObject would
    be assumed to be the parameteric type. The second
    one would require that the parameter (if present at
    time of variable of declaration is instantiation) be
    at least as specific as the current extenstion of
    BaseObject.Yes, exactly. This would be wildly helpful. Oh well.
    Back to 1.4 syntax.
    Cheers,
    Laird

  • Generic worker threads using reflection?

    Many of my classes have methods that take a long time to finish. I am doing ok, but am unhappy with the design. I want a clean divide between the time consuming algorithm methods and threading. So this is what I came up with:
    public class Main {
      public static void main(String[] args) {
        Class[] cArgs = new Class[1];
        cArgs[0] = (new double[1]).getClass();
        Method m = Algorithms.class.getMethod("transform", cArgs);
        Object[] objArgs = new Object[1];
        objArgs[0] = data;
        Worker w = new Worker(m, null, objArgs);
        w.start();
        // do some other work.
        // sometimes check-in and test if the worker has finished.
        // might need to use "synchronized(w) {}" and "w.wait()"
        double[] result = (double[]) w.getResult();
    public class Algorithms {
      static double[] transform(double[] vector) {
        // do work....
        return results;
      // more static methods...
    public class Worker extends Thread {
      Method m;
      Object obj;
      Object[] args;
      Object returnValue;
      boolean started = false;
      boolean finished = false;
      Worker(Method m, Object obj, Object[] args) {
        this.m = m; this.obj = obj; this.args = args;
      public void run() {
        synchronized (this) {
          started = true;
          returnValue = m.invoke(obj, args);
          finished = true;
      public Object getResult() { return returnValue; }
      public boolean isStarted() { return started; }
      public boolean isFinished() { return finished; }
    }I don't quite yet understand the complete mechanics of thread sync, but in the simple testing so far the parallelism has worked as expected.
    To me, that conceptually looks like a clean split between the algorithms and the parallelism. However, implementation-wise that looks pretty sketchy. Reflection alone should almost never be used. Threading correctly is very difficult. Combining the two just seems like a really bad idea, yet I really like the design and can't think of any good alternatives that adhere to best practices oop concepts. Any advice would be welcomed.

    rerf wrote:
    Peter__Lawrey wrote:
    rerf wrote:
    My only observation was that static methods and interfaces conceptually have no connection. Thus, static methods are not allowed in interfaces. Development is about bring together elements from different concepts. You sound like you are trying to keep your code "pure", but provide no justication for doing so.Only justification is self-study. I had been programming along quickly, and then it got so messy I wanted to stop and redo everything using best-practices oop concepts as I understand them.In that case I would point out that static methods don't follow the OOP model. Perhaps you could drop the static methods.
    So, when I write a static method I should never think about interfaces. static methods can have interfaces as parameter types, and can call methods on interfaces, and interface method implementations can call static methods. Again your need to keep these seperate makes no sense to me.What I mean is that I do not want the class to which the cpu intense algorithm belongs to have to implement Runnable or Callable.Then I suggest you call the "class to which the cpu intense algorithm" from another/anonymous class which implements Runnable ro Callable.
    My unit of work is not an entire object (rather its one static method). So, how can I get a thread to execute that? A non-static method can call a static method. Is there really a need to make things any more complicated than that?I did not know. I am trying to find a coding style.
    While re-writing my code, and trying to be oop, I realized all I needed was the method, its parameters, the return value, and a thread to execute it. But when I got into the reflection, I decided its probably a bad idea, but still decided to ask for a second opinion. as well as a possible alternative.An anonymous class like Runnable to wrap the method and its arguments. I suggest Runnable instead of Callable, because you have to do something with the result which the Runnable can do in the same thread. The Callable passes the result back to the calling thead to process which is usually more complicated and less efficient.
    I am still not sure of the best way to deal with executing static methods in parallel. Here is the signature of a method I will run tonight in batch.
    static void patternMatch(Reader in, Writer out, Connection conn) throws Exception;
    I want to invoke that method 10-times and have the data processing happen in parallel.
    public static void main(String... args) {
    Executor exectors = Executors.newFixedThreadPool(N_THREADS);
    for(int i=0;i<10;i++) {
      final Reader in = ....
      final Writer out = ....
      final Connection conn = ...
      executor.executor(new Runnable() {
        public void run() {
            try {
                patternMatch(in, out, conn);
            } catch (Throwable t) { // I suggest you catch Throwable even if there are no checked exceptions or they can be discarded.
                // handle t
    executor.shutdown(); // shutdown when finished.
    // no need to wait as there is nothing to do when finished.
    When all the threads finish, the main method can exit.Why? What would happen if the main method exited when there was nothing left for it to do?

  • Problem referencing to methods with generic type parameters

    Assuming I have an interface like to following:
    public interface Test <T> {
    void test ( T arg0 );
    void test ( T arg0, Object arg1 );
    I would like to reference to both "test"-methods using "{@link #test(T)}" and "{@link #test(T,Object)}".But this generates an error telling me "test(T)" and "test(T,Object)" cannot be found.
    Changing T to Object in the documentation works and has as interesing effect. The generated link text is "test(Object)" but the generated link is "test(T)".
    Am I somehow wrong? Or is this a known issue? And is there a workaround other than using "Object" instead of "T"?

    Hi,
    I bumped into the same problem when documenting a generic.
    After quite a while of search your posting led me to the solution.
    My code goes something like this:
    public class SomeIterator<E> implements Iterator<E> {
      public SomeIterator(E[] structToIterate) {
    }When I tried to use @see or @link with the constructor Javadoc never found it.
    After I changed the documentation code to
    @see #SomeIterator(Object[])it worked.
    Since both taglets offer the use of a label, one can easily use these to produce comments that look correct:
    @see #SomeIterator(Object[]) SomeIterator(E[])CU
    Froestel

  • Instantiation of generic type

    Hi.
    I have an issue with instantiating of generic type. My issue is similar to this Re: creating instance of generic type post.
    So I have the following class
    public class VehicleForm<V extends Vehicle>{
    private V vehicle;
    private Double price;
    private Class<V>vItemClass;
    public V getVehicle(){
    return this.vehicle;
    public void setVehicle(V vehicle){
    this.vehicle=vehicle;
    public Double getPrice(){
    return this.price;
    public void setPrice(Double price){
    this.price=price;
    private final Class<V> getGenericClassInstance() {
    Class<V> persistentClass = null;
    Type genericType = getClass().getGenericSuperclass();
    if (genericType instanceof ParameterizedType) {
    ParameterizedType pType = ((ParameterizedType) genericType);
    // obtaining first generic type class
    persistentClass = (Class<V>) pType.getActualTypeArguments()[0];
    return persistentClass;
    public VehicleForm(){
    this.vItemClass=getGenericClassInstance();//vItemClass is null
    this.vehicle=this.vItemClass.newInstance();//null poiner exception
    I cannot write in default constructor
    public VehicleForm(){
    this.vehicle=new V();//runtime error will occure
    because of generic type
    For obtaining generics we can use java reflection functionality. Generic type list in runtime is obtaining through ParameterizedType. The code in getGenericClassInstance is standard to instantiate generic type var.
    But unfortunately in my case it doesn't work. getGenericClassInstance returns null. Line Type genericType = getClass().getGenericSuperclass(); doesnt get generic type which is instance of ParameterizedType, so the condition if (genericType instanceof ParameterizedType) is false. My genericType is Object instance, but not ParameterizedType. So I cannot create Class<V> instance from null.
    Can anybody help me? Thanks in advance.
    Edited by: 877736 on 06.08.2011 12:50
    Edited by: 877736 on 06.08.2011 12:51

    877736 wrote:
    My issue is similar to this Re: creating instance of generic type post...Did you look at the answers given there? Pretty much the same as ttjacobs is telling you here: This is NOT what generics was created for.
    Even if you can do it, the code is likely to be messy, complex and brittle.
    Also: this thread is in the wrong category, as the other poster (you?) was already told. There is a "Generics" section under Java APIs.
    My suggestion: rethink your solution.
    Winston

  • Generic type doesn't support raw dataypes (int, boolean, etc.)?

    It seems that Java 5 generics always autoboxes raw datatypes (int, double, boolean, ...) to the wrapper classes (Integer, Double, Boolean, ...), because when I use e.g. Integer.TYPE (instead of Integer.class), I got ClassCastExceptions. Is this non-support somewhere written down or is there a way to handle raw types without autoboxing them to their wrapper class?

    I'm having some difficulty understanding your question, but my first suggestion is to see section 4.4 Type Variables of the Java Language Specification, which states: "If no bound is given for a type variable, Object is assumed."
    Also, I think you mean "primivite" instead of "raw" types. Raw types are the "name of a generic type declaration used without any accompanying
    actual type parameters" (sectoin 4.8 Raw Types).
    Regards,
    Nick

  • Define structure with table type fields using keyword "TYPES"

    Hi Gurus,
    Using keyword "TYPES", I want to define a structure in which there is a field must be table type. It seems not allowed. For example:
        TYPES tt_items TYPE TABLE OF sflight.
        TYPES: BEGIN OF str,
          field1 TYPE i,
          field_tabl TYPE tt_items.
        TYPES:  END OF str.
    Then I got a syntax error:
    "TT_ITEMS" is a generic type. Use of this type is only possible for     typing field symbols and formal parameters. -     
    What should I do if I want to have a table type field in it?
    Thanks a lot.

    include type EKKO includes the whole strucutre of EKKO.
    if you see the structure in debug mode, it_ekko contains the fields of EKKO as well as the field CHK of type C.
    In your case you can do this
    TYPES: BEGIN OF str.
    INCLUDE TYPE sflight.  " includes whole structure of SFLIGHT
    TYPES : field1 TYPE i. " include the field1 of type I
    TYPES: END OF str.
    DATA : it_str TYPE TABLE OF str, " internal table
           is_str TYPE str.          " work area
    Regards
    Gopi

  • Import from database an internal table with generic Type : Web Dynpro ABAP

    Hi everyone,
    i have a requirement in which i'm asked to transfer data flow between two frameworks, from WD Component to another. The problem is that i have to transfer internal tables with generic types. i used the import/ export from database approache but in that way i get an error message saying "Object references and data references not yet supported".
    Here is my code to extract a generic internal table from memory.
        DATA l_table_f4 TYPE TABLE OF REF TO data.
      FIELD-SYMBOLS: <l_table_f4> TYPE STANDARD TABLE.
      DATA lo_componentcontroller TYPE REF TO ig_componentcontroller .
      DATA: ls_indx TYPE indx.
      lo_componentcontroller =   wd_this->get_componentcontroller_ctr( ).
      lo_componentcontroller->fire_vh_search_action_evt( ).
      ASSIGN l_table_f4 TO <l_table_f4>.
    *-- Import table for Help F4
      IMPORT l_table_f4 TO <l_table_f4> FROM DATABASE indx(v1) TO ls_indx ID 'table_help_f4_ID'.
    The error message is desplayed when last instruction is executed " IMPORT l_table_f4...".
    I saw another post facing the same problem but never solved "Generic Type for import Database".
    Please can anyone help ?
    Thanks & Kind regards.

    hi KIan,
    go:
    general type
    TYPE : BEGIN OF ty_itab,
               field1 TYPE ztab-field1,
               field2 TYPE ztab-field2,
    *your own fields here:
               field TYPE i,
               field(30) TYPE c,
               END OF ty_itab.
    work area
    DATA : gw_itab TYPE ty_itab.
    internal table
    DATA : gt_itab TYPE TABLE OF ty_itab.
    hope this helps
    ec

  • How To: Use reflection to create instance of generic type?

    I would like to be able to use reflection to instantiate an instance of a generic type, but can't seem to avoid getting type safety warnings from the compiler. (I'm using Eclipse 3.1.1) Here is a trivial example: suppose I want to create an instance of a list of strings using reflection.
    My first guess was to write the following:
    Class cls = Class.forName("java.util.ArrayList<String>");
    List<String> myList = cls.newInstance();The call to Class.forName throws a ClassNotFoundException. OK, fine, so I tried this:
    Class cls = Class.forName("java.util.ArrayList");
    List<String> myList = cls.newInstance();Now the second line generates the warning "Type safety: The expression of type List needs unchecked conversion to conform to List<String>".
    If I change the second line to
    List<String> myList = (List<String>)cls.newInstance();then I get the compiler warning "Type safety: The cast from Object to List<String> is actually checking against the erased type List".
    This is a trivial example that illustrates my problem. What I am trying to do is to persist type-safe lists to an XML file, and then read them back in from XML into type-safe lists. When reading them back in, I don't know the type of the elements in the list until run time, so I need to use reflection to create an instance of a type-safe list.
    Is this erasure business prohibiting me from doing this? Or does the reflection API provide a way for me to specify at run time the type of the elements in the list? If so, I don't see it. Is my only recourse to simply ignore the type safety warnings?

    Harald,
    I appreciate all your help on this topic. I think we are close to putting this thing to rest, but I'd like to run one more thing by you.
    I tried something similar to your suggestion:public static <T> List<T> loadFromStorage(Class<T> clazz) {
        List<T> list = new ArrayList<T>();
        for ( ...whatever ...) {
           T obj = clazz.newInstance();
           // code to load from storage ...
           list.add(obj);
        return list;
    }And everything is fine except for one small gotcha. The argument to this method is a Class<T>, and what I read from my XML storage is the fully qualified name of my class(es). As you pointed out earlier, the Class.forName("Foo") method will return a Class<?> rather than a Class<Foo>. Therefore, I am still getting a compiler warning when attempting to produce the argument to pass to the loadFromStorage method.
    I was able to get around this problem and eliminate the compiler warning, but I'm not sure I like the way I did it. All of my persistent classes extend a common base class. So, I added a static Map to my base class:class Base
       private static Map<String, Class<? extends Base>> classMap = null;
       static
          Map<String, Class<? extends Base>> map = new TreeMap<String, Class<? extends Base>>();
          classMap = Collections.synchronizedMap(map);
       public static Class<? extends Base> getClass(String name)
          return classMap.get(name);
       protected static void putClass(Class<? extends Base> cls)
          classMap.put(cls.getName(), cls);
    }And added a static initializer to each of my persistent classes:class Foo extends Base
       static
          Base.putClass(Foo.class);
    }So now my persistence code can replace Class.forName("my.package.Foo") with Base.getClass("my.package.Foo"). Since Foo.class is of type Class<Foo>, this will give me the Class<Foo> I want instead of a Class<?>.
    Basically, it works and I have no compiler warnings, but it is unfortunate that I had to come up with my own mechanism to obtain a Class<Foo> object when my starting point was the string "my.package.Foo". I think that the JDK, in order to fully support reflection with generic types, should provide a standard API for doing this. I should not have to invent my own.
    Maybe it is there and I'm just not seeing it. Do you know of another way, using reflection, to get from a string "my.package.Foo" to a Class<Foo> object?
    Thanks again for your help,
    Gary

  • Finding type of primitive at runtime using Reflection !!

    Hi,
    Is there any way to get the type of primitive using reflection.
    Consider the scenario :
    String classType = "java.lang.Integer";
    String paramValue = "10";
    Class classObj = Class.forName( classType );
    Object obj = classObj.getConstructor( new Class[] {String.class } ).
    newInstance(new Object[] { paramValue }) ) ;
    java.lang.Integer defines a variable called TYPE which returns the type, but in the above line newInstance returns an Object and not Integer
    Is there a way to find the type of primitive from the above code
    considering that the classType variable can change?
    Any help is greatly appreciated .
    Regards,
    Harsha

    Your scenario is wrong, you are creating an instance of Integer which is not primitive.
    You need to create a scenario like this..
    When querying a class for a Field then you can determine if the Field is primitive
    Class clazz = obj; //** Where obj is any object
    Field f = clazz.getDeclaredField( "field" );
    Class fieldType = f.getType();
    if( f.getType().isPrimitive() ) {
      if( fieldType.equals( Byte.TYPE ) {
        System.out.println( "Field: field is byte primitive" );
      //** repeat for each type
    //** get the value of the field for obj and print it out
    System.out.println( "Field value = " + f.getValue( obj ) );Obviously this is not really useful when you want to do something sensible with the value of the field.
    You need to expand on what it is you are trying to achieve.

  • Extends collection using generic type of org.w3c.dom.Element

    Hi, all.
    I am trying to extending collection using PriorityBlockingQueue.
    Extended queue is generic type of org.w3c.dom.Element.
    public class MyQueue<Element> extends PriorityBlockingQueue<Element> {***/}
    Compiler misunderstand to type of Element (as like E ?, not org.w3c.dom.Element), then methods in the code "this.peek ()" will be error reported by type difference.
    At fact, I tried it into MyQueue<Node> extends PriorityBlockingQueue<Node>, it not causes any misunderstanding.
    Is there any hack to indicates that the type is org.w3c.dom.Element ? This mean, MyQueue<org.w3c.dom.Element> extends PriorityBlockingQueue<org.w3c.dom.Element>...
    Thanks.

    public class MyQueue extends PriorityBlockingQueue<org.w3c.dom.Element>

  • Generic method invocations with explicit type parameters

    If I interpret the JSR14 public draft spec (June 23, 2003) section 5.6 correctly the following method invocations with explicit type parameters should compile: package generics;
    public class G121 {
      void f() {
        this.<String>f2();
        <String>f2(); // compilation error
        <String>f3(); // compilation error
      <T> void f2() {
      static <T> void f3() {
    }but the class does not compile: jc -J-showversion generics\G121.javajava version "1.5.0-beta"
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b32c)
    Java HotSpot(TM) Client VM (build 1.5.0-beta-b32c, mixed mode)
    generics\G121.java:6: illegal start of expression
        <String>f2(); // compilation error
                ^
    generics\G121.java:8: illegal start of expression
        <String>f3(); // compilation error
                ^
    2 errors
    >A bug or do I miss something?

    I get this error:
    LineCount.java:104: cannot find symbol
    symbol : method <java.io.File>sort(java.util.List<java.io.File>)
    location: class java.util.Collections
    Collections.<File>sort( list );
    ^
    1 errorYou don't need the explicit type argument there, but anyway...
    If you look at the docs for Collections.sort(List<T> list) you'll see it is declared as:
    static <T extends Comparable<? super T>> void Collections.sort(List<T> list) Unfortunately, although File implements Comparable, it doesn't actually implement Comparable<File> or even Comparable<Object>, so I guess it can't satisfy the bound.
    You can get it to compile by removing the explicit type argument and casting to the raw type List, but that's not very nice.
    This seems like an oversight to me - File already has both int compareTo(Object o) and int compareTo(File pathname) so I don't see why it can't implement Comparable<File>. This isn't the only such case in the API though, so maybe I'm missing something.
    Mark

  • Generic Delta Update using Function Module........ problem with CURR  type

    Hi Experts,
    I try to create a generic data source using the transaction RSO2. I got the following error message
    " Das Einheitenfeld CURR des Feldes ZPKZA1 der DataSource ZBWN_DS_POLPOSP ist ausgeblendet"
    "The unit field CURR of the field ZPKZA1 of the DATA SOURCE ZBWN_DS_POLPOSP is not visible/ stopped/ hide".
    How shall i handle this issue..........any suggestions please........
    thanks in advance
    Cheers
    Jaya

    Hi Jaya ,
    The error msg which is coming as...
    "The unit field CURR of the field ZPKZA1 of the DATA SOURCE ZBWN_DS_POLPOSP is not visible/ stopped/ hide" may be due to the currency field made hidden at the data source lavel. Also check weather you have included it in your structure (code).
    So, to check it and make it unhide go to "Display Field List (F7)" in RSO2.
    Hope it helps.

  • Retrieving generic type and letter

    Hi,
    I have a generic class -
    public class AAA <T extends BBB>implements Serializable From which I want to get its generic type (the easy part),
    and the generic type letter representation (In this case - T).
    Can I do this by reflection? If so how,
    Otherwise - is there any way I can do that which doesn't involve parsing the class as text?
    Thanks,
    Sharon.

    Class.getGenericDeclaration() should lead you to the letter T.
    The actual runtime type cannot be obtained because of erasure.
    If the class is under your control, you can play a trick:
    add to the constructor(s) a Class parameter and pass the actual type
    used.

  • A Universal Comparator using reflections

    Folks,
    <edit purpose="bump" secondaryPurpose="explain stuff a bit better">
    Sorry I didn't explain what this thing is... and zero bites in the veiw of several active silver backs means, I presume, that I did something magorly wrong... so...
    This class class calls the compare method passing the result of named "getter" method on the two objects to compare. So what? Well... Ummm... It means you can sort by any field of any List (or PriorityQueue, or what-have-you) without having to pre-write a Comparator.... Which is good.
    </edit>
    I was inspired by a blog entry by ?was it warnerja? which was referenced in a thread which was linked from an off-topic post in a thread I read last ?Thursday? night... and to cut a long storry short... I can't find the blog entry again :(
    My implementation is based on [this one by Lone Deranger|http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=3308&lngWId=2] ... which has a couple of problems
    1. infinite recursion in the equals method == OutOfStackSpaceException
    2. It gets the method defintion every time you call compare == sloooooooooooowwwwwwwwwww.
    This version
    * is a bit faster
    * verifies as much as possible in constructor.
    * uses generics to verify (as far as possible) the runtime "compared Class" type.
    But I'm pretty sure someone who really knows there generics could improve upon the implementation (or quit possibly the fundamental design). Specifically I'm not in love passing the Class of the compared objects as well as define the generic type. There's GOT to be a better way... I'm just to inexpert/stupid to recognise it... I've probably been staring straight at it for the last two hours.
    So.... This thing works... but any suggestions and/or constructive criticism would be welcome ;-) Thanx.
    UniversalReflectiveComparator.java
    package forums;
    import java.util.Comparator;
    import java.lang.reflect.Method;
    import java.lang.reflect.Type;
    public class UniversalReflectiveComparator<T> implements Comparator<T>
      public static String DEFAULT_METHOD_NAME = "toString";
      public static final int ASCENDING = 1;
      public static final int DESCENDING = -1;
      public static int DEFAULT_ORDER = ASCENDING;
      private static final java.lang.Object[] NO_ARGS = null;
      private final String methodName;
      private final Method getterMethod;
      private final int order;
      public UniversalReflectiveComparator(Class classToCompare)
        throws NoSuchMethodException
        this(classToCompare, DEFAULT_METHOD_NAME, DEFAULT_ORDER);
      public UniversalReflectiveComparator(Class classToCompare, String methodName)
        throws NoSuchMethodException
        this(classToCompare, methodName, DEFAULT_ORDER);
      public UniversalReflectiveComparator(Class classToCompare, int order)
        throws NoSuchMethodException
        this(classToCompare, DEFAULT_METHOD_NAME, order);
      @SuppressWarnings("unchecked")
      public UniversalReflectiveComparator(Class classToCompare, String methodName, int order)
        throws NoSuchMethodException
        getterMethod = classToCompare.getMethod(methodName, (java.lang.Class<?>[])null);
        Class returnType = getterMethod.getReturnType();
        if ("void".equals(returnType.getName())) {
          throw new IllegalArgumentException("Cannot compare on the '"+methodName+"' method"
          + " because its return type is void (ie: it does not return a value to compare).");
        if ( !doesImplement(returnType, Comparable.class.getCanonicalName()) ) {
          throw new IllegalArgumentException("Cannot compare on the '"+methodName+"' method"
          + " because its return type '"+returnType.getName()+"' does not implement Comparable.");
        this.methodName = methodName;
        this.order = order;
      @Override
      @SuppressWarnings("unchecked")
      public int compare(T o1, T o2) {
        try {
          Comparable o1attribute = (Comparable) getterMethod.invoke(o1, NO_ARGS);
          Comparable o2attribute = (Comparable) getterMethod.invoke(o2, NO_ARGS);
          return o1attribute.compareTo(o2attribute) * order;
        } catch (Exception e) {
          throw new IllegalStateException("Failed to compare "+clazz(o1)+ " to "+clazz(o2), e);
       * Returns the type and string value of the given object.
       * eg: java.lang.String 'Hello World!'
      private static String clazz(Object object) {
        return object.getClass().getCanonicalName()+" '"+String.valueOf(object)+"'";
       * Returns: Does the given clazz implement the given interfaceName
       * @param clazz the Class to be examined.
       * @param canonicalInterfaceName the full name (with or without generics)
       *  of the interface sought: path.to.Interface[<path.to.GenericType>]
      private static boolean doesImplement(Class clazz, String canonicalInterfaceName) {
        for ( Type intrface : clazz.getGenericInterfaces() ) {
          if ( intrface.toString().startsWith(canonicalInterfaceName) ) {
            return true;
        return false;
    UniversalComparatorTest.java
    package forums;
    import java.util.List;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.io.FileReader;
    import java.io.BufferedReader;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    // A simple "Bean" class for testing only.
    // Does NOT implement comparable!
    class Word {
      private final String word;
      public Word(String word) { this.word=word; }
      public String getWord() {  return this.word; }
      public void noop() { }
      public String toString() { return this.word;  }
      public Word notComparable() { return new Word("notComparable"); }
    class UniversalComparatorTest
      @SuppressWarnings("unchecked")
      public static void main(String[] args) {
        try {
          List<Word> words = readWords("WordFinder.txt");
          System.err.println("---------------------------------------------------");
          // SUCCESS CASES
                           //short for new UniversalReflectiveComparator<Word>(Word.class,"toString",ASCENDING);
          try {
            Collections.sort(words, new UniversalReflectiveComparator<Word>(Word.class));
            System.out.println(words);
          } catch (Exception e) {e.printStackTrace();}
          System.err.println("---------------------------------------------------");
          try {
            Collections.sort(words, new UniversalReflectiveComparator<Word>(Word.class, "getWord", UniversalReflectiveComparator.DESCENDING));
          } catch (Exception e) {e.printStackTrace();}
          System.out.println(words);
          System.err.println("---------------------------------------------------");
          try {
            Collections.sort(words, new UniversalReflectiveComparator<Word>(Word.class, UniversalReflectiveComparator.DESCENDING));
          } catch (Exception e) {e.printStackTrace();}
          System.out.println(words);
          System.err.println("---------------------------------------------------");
          // FAIL CASES
          try {
            Collections.sort(words, new UniversalReflectiveComparator<Word>(Word.class, "nonExistantMethodName"));
          } catch (Exception e) {e.printStackTrace();}
          System.err.println("---------------------------------------------------");
          try {
            Collections.sort(words, new UniversalReflectiveComparator<Word>(Word.class, "noop"));
          } catch (Exception e) {e.printStackTrace();}
          System.err.println("---------------------------------------------------");
          try {
            Collections.sort(words, new UniversalReflectiveComparator<Word>(Word.class, "notComparable"));
          } catch (Exception e) {e.printStackTrace();}
          System.err.println("---------------------------------------------------");
        } catch (Exception e) {
          e.printStackTrace();
       * reads each line of the given file into a List of strings.
       * @param String filename - the name of the file to read
       * @return an List handle ArrayList of strings containing file contents.
      public static List<Word> readWords(String filename) throws FileNotFoundException, IOException {
        List<Word> results = new ArrayList<Word>();
        BufferedReader reader = null;
        try {
          reader = new BufferedReader(new FileReader(filename));
          String line = null;
          while ( (line=reader.readLine()) != null ) {
            results.add(new Word(line));
        } finally {
          if(reader!=null)reader.close();
        return results;
    }Cheers all. Keith.
    PS: If you happen to know that blog entry... could you post a link... please.
    Edited by: corlettk on 2/11/2008 15:52 - Ooops!
    Edited by: corlettk on 2/11/2008 18:20 - You Snobs!
    Edited by: corlettk on 2/11/2008 19:00 - Dodgems bump!

    Here's the latest installment...
    This thing writes, compiles and instantiates and caches the requested implementation of Comparator<?> on-the-fly with the system default javax.tools.JavaCompiler
    Some Notes:
    * Gee, it's just sooooo easy to invoke the compiler.
    * Compilation errors are printed to stdout.
    * It takes too long to compile... aprox nine-tenths of a second (0.95 +/- 0.04) for a really simple little class.
    * I like the cache... subsequent calls for the same comparator are instant ;-)
    * Possible enhancement: oninit: load the cache with .class's from the specified package (a seperate comparators package), so you only have to create each comparator once per release (ie: like JSP's)
    * It throws too many distinct exception types... I think it would be better if it threw only one ComparatorGenerationException (but I'm too lazy to fix it now).
    * I don't like the "staticness" anymore, especially with a cache involved. Maybe a ComparatorFactoryConfig extends Properties would be the best way to configure the factory? Or maybe a ComparatorSpec class should be passed to the createComparator method... to eliminate all that cumbersome overloading to just to provide defaults. Hmmm.
    * The order switch means you can sort both ways using the one generated
    * A simillar "nulls first or last" switch would be a good enhancement.
    * Camickr's solution also features a case[in]senstive switch... feel free to add it ;-)
    * It's still not a scratch on Mr Kirkman's ASM solution (which is aprox 10 times as fast), but it'll definately give the "pure reflection" solution a run for it's money.
    * I can imagine a common "front end" for both the "reflective" and "code-gen" solutions... if the list size is less than 10,000 just reflect it, else code-gen.
    UniversalOnTheFlyCompiledComparatorFactory.java
    package forums;
    import java.util.Comparator;
    import java.lang.reflect.Method;
    import java.lang.reflect.Type;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.PrintWriter;
    import java.io.IOException;
    import java.util.Arrays;
    import java.util.Map;
    import java.util.HashMap;
    import javax.tools.DiagnosticCollector;
    import javax.tools.JavaCompiler;
    import javax.tools.JavaFileObject;
    import javax.tools.StandardJavaFileManager;
    import javax.tools.ToolProvider;
    public class UniversalOnTheFlyCompiledComparatorFactory
      public static String DEFAULT_METHOD_NAME = "toString";
      public static String SRC_DIR = "C:/java/home/src/";
      public static String PACKAGE = "forums";
      public static final int DESCENDING = -1;
      public static final int ASCENDING = 1;
      public static int DEFAULT_ORDER = ASCENDING;
      private static final java.lang.Class<?>[] NULL_CLASS_ARRAY = null;
      public static Comparator createComparator(Class classToCompare)
        throws NoSuchMethodException, IOException, CompilationException, ClassNotFoundException, InstantiationException, IllegalAccessException
        return createComparator(classToCompare, DEFAULT_METHOD_NAME, DEFAULT_ORDER);
      public static Comparator createComparator(Class classToCompare, String methodName)
        throws NoSuchMethodException, IOException, CompilationException, ClassNotFoundException, InstantiationException, IllegalAccessException
        return createComparator(classToCompare, methodName, DEFAULT_ORDER);
      public static Comparator createComparator(Class classToCompare, int order)
        throws NoSuchMethodException, IOException, CompilationException, ClassNotFoundException, InstantiationException, IllegalAccessException
        return createComparator(classToCompare, DEFAULT_METHOD_NAME, order);
      public static Map<String,Comparator<?>> cache = new HashMap<String,Comparator<?>>();
      @SuppressWarnings("unchecked")
      public static Comparator createComparator(Class classToCompare, String methodName, int order)
        throws NoSuchMethodException, IOException, CompilationException, ClassNotFoundException, InstantiationException, IllegalAccessException
        final String key = classToCompare.getName()+"."+methodName+"_"+order;
        Comparator<?> comparator = cache.get(key);
        if (comparator != null) {
          return comparator;
        final Method getterMethod = classToCompare.getMethod(methodName, NULL_CLASS_ARRAY);
        final Class returnType = getterMethod.getReturnType();
        if ("void".equals(returnType.getName())) {
          throw new IllegalArgumentException("Cannot compare on the '"+methodName+"' method because its return type is void (ie: it does not return a value to compare).");
        if ( !isComparable(returnType) ) {
          throw new IllegalArgumentException("Cannot compare on the '"+methodName+"' method because its return type '"+returnType.getName()+"' does not implement Comparable.");
        final File javaFile = writeComparatorJava(classToCompare, getterMethod, order);
        if ( ToolProvider.getSystemJavaCompiler().run(null, System.out, System.err, javaFile.getName()) != 0 ) {
          throw new CompilationException("Failed to compile comparator file: "+javaFile.getAbsolutePath());
        final String comparatorClassName = PACKAGE+"."+javaFile.getName().replaceAll("\\.java$", "");
        comparator = (Comparator<?>) Class.forName(comparatorClassName).newInstance();
        cache.put(key, comparator);
        return comparator;
      private static File writeComparatorJava(Class classToCompare, Method getterMethod, int order)
        throws IOException, CompilationException
        final String nameOfClassToCompare = classToCompare.getName().replaceAll("^.*(?=\\.)\\.",""); // remove everything before the last .
        final String getterMethodName = getterMethod.getName();
        final String comparatorClassName = nameOfClassToCompare + getterMethodName.replaceAll("^get","").replaceAll("toString","String") + "Comparator";
        final File comparatorClassFile = new File(SRC_DIR+PACKAGE+"/"+comparatorClassName+".java");
        PrintWriter out = null;
        try {
          out = new PrintWriter(new FileWriter(comparatorClassFile));
          out.println("package "+PACKAGE+";");
          out.println("public class "+comparatorClassName+" implements java.util.Comparator<"+nameOfClassToCompare+">");
          out.println("{");
          out.println("  public static final int DESCENDING = -1;");
          out.println("  public static final int ASCENDING = 1;");
          out.println("  public static final int DEFAULT_ORDER = "+order+";");
          out.println("  public final int order;");
          out.println();
          out.println("  public "+comparatorClassName+"() { this(DEFAULT_ORDER); }");
          out.println();
          out.println("  public "+comparatorClassName+"(int order) { this.order = order; }");
          out.println();
          out.println("  // nulls come last");
          out.println("  public int compare("+nameOfClassToCompare+" a, "+nameOfClassToCompare+" b) {");
          out.println("    if (a==null) {");
          out.println("      return b==null ? 0 : -1;");
          out.println("    } else {");
          out.println("      return b==null ? 1 : a."+getterMethodName+"().compareTo(b."+getterMethodName+"()) * order;");
          out.println("    }");
          out.println("  }");
          out.println();
          out.println("}");
        } finally {
          if (out!=null)out.close();
        return comparatorClassFile;
       * Returns: Does the given clazz implement the given interfaceName
       * @param clazz the Class to be examined.
       * @param canonicalInterfaceName the full name (with or without generics)
       *  of the interface sought: path.to.Interface[<path.to.GenericType>]
      private static boolean isComparable(Class clazz) {
        for ( Type i : clazz.getGenericInterfaces() ) {
          if ( i.toString().startsWith("java.lang.Comparable") ) {
            return true;
        return false;
    UniversalComparatorTest.java
    package forums;
    import java.util.List;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.io.FileReader;
    import java.io.BufferedReader;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    // A simple "Bean" class for testing only.
    // Does NOT implement comparable!
    class Word {
      private final String word;
      public Word(String word) { this.word=word; }
      public String getWord() {  return this.word; }
      public void noop() { }
      public String toString() { return this.word;  }
      public Word notComparable() { return new Word("notComparable"); }
    class UniversalComparatorTest
      @SuppressWarnings("unchecked")
      public static void main(String[] args) {
        try {
          List<Word> words = readWords("WordFinder.txt");
          System.err.println("---------------------------------------------------");
            long start = System.nanoTime();
            try {
              Comparator<Word> wordComparator = UniversalOnTheFlyCompiledComparatorFactory.createComparator(Word.class);
              Collections.sort(words, wordComparator);
              System.out.println(words);
            } catch (Exception e) {e.printStackTrace();}
            long stop = System.nanoTime();
            System.err.printf("took %6.4f seconds%n", (stop-start)/1000000000.0);
            System.err.println("---------------------------------------------------\n");
            long start = System.nanoTime();
            try {
              Comparator<Word> wordComparator = UniversalOnTheFlyCompiledComparatorFactory.createComparator(Word.class);
              Collections.sort(words, wordComparator);
              System.out.println(words);
            } catch (Exception e) {e.printStackTrace();}
            long stop = System.nanoTime();
            System.err.printf("took %6.4f seconds%n", (stop-start)/1000000000.0);
            System.err.println("---------------------------------------------------\n");
        } catch (Exception e) {
          e.printStackTrace();
       * reads each line of the given file into a List of strings.
       * @param String filename - the name of the file to read
       * @return an List handle ArrayList of strings containing file contents.
      public static List<Word> readWords(String filename) throws FileNotFoundException, IOException {
        List<Word> results = new ArrayList<Word>();
        BufferedReader reader = null;
        try {
          reader = new BufferedReader(new FileReader(filename));
          String line = null;
          while ( (line=reader.readLine()) != null ) {
            results.add(new Word(line));
        } finally {
          if(reader!=null)reader.close();
        return results;
    }Cheers. Keith.
    It's Bed Time ;-)

Maybe you are looking for

  • Wireless apple keyboard not pairing at set up of new mac mini

    i have just purchased a new mac mini and wireless keyboard and trackpad. i am trying to setup my mac mini but the keyboard does not pair. i have tried replacing the batteries. but as i am new to macs i dont have much of a clue. the trackpad connects

  • IPhone 3.0 update Firmware File Corrupt & Don't Have Enough Access Privileg

    I'm trying to update to the new 3.0 firmware version for the iPhone. Once the download is complete I get two error messages, the first (The iPhone " " could not be restored/updated because the firmware file was corrupt) the second (There was a proble

  • Add WebService does not work

    The WSDL: http://studentmasjid.com/Quran/QuranService.wsdl I have the "Check WS-I" and "Generate SOAP Headers" on/off does not matter, and it will give me this error: Start http://studentmasjid.com/Quran/QuranService.wsdl 10/22/2006 17:14:12: Parsing

  • Unable detect a flash drive.

    i got this mp3 player that acts as a flash drive (samsung yp-t7f). it cannot be detected by my apple ibook. is there anyway to solve this problem? by installing drivers? thx.

  • Update AD values

    Hello, We are trying to loop through a recordset to update AD values that have changed.  If the value for a particular property in AD already exists (ie middle initial) then updating that value to another works great.  The problem arrises that when t