3 Replies Latest reply: Sep 9, 2010 2:16 PM by 843793 RSS

    Java | Checking Type in Generic Collection

    843793
      Java | Checking Type in Generic Collection

      Hello There,
      How can I check the original type of the object in any generic collections like Vector, ArrayList, HashMap.

      See:
      If I have this line of code...
      ArrayList<?> AL = DBConn.getDbRecordsByQuery();
      Now, Here I am fully confused about type of the values containing by ArrayList AL.

      Please help to to check the type of the collection in ArrayList.

      Thanks a lot in pre
      :)
        • 1. Re: Java | Checking Type in Generic Collection
          843793
          Hello VINAY_Kr_SHARMA,

          I'm not quite certain what you are trying to achieve. If you are trying to figure out what type argument was used to construct the ArrayList (i.e. the E in ArrayList<E>), you are out of luck; Java does not reify type arguments.

          With kind regards
          Ben
          • 2. Re: Java | Checking Type in Generic Collection
            forumKid2
            I'm not sure if this will help but can't you do something like this, testing the value
            if(AL.get(0) instanceof String){
            // string
            }else if(AL.get(0) instanceof Number){
            // number
            }
            Or
            Object o  = DBConn.getDbRecordsByQuery();
            if(o instanceof Vector){
            //vector
            }
            These are just quick examples, not tested for compilation
            • 3. Re: Java | Checking Type in Generic Collection
              843793
              ForumKid2 wrote:
              I'm not sure if this will help but can't you do something like this, testing the value
              if(AL.get(0) instanceof String){
              // string
              You can, but that test doesn't rule out AL being an ArrayList<Object> or ArrayList<CharSequence>.

              Basically any time you are trying to glean type parameters at runtime with Java generics, you're using generics in an improper way or for the wrong purpose.

              Instead what you could do is create a library function that checks each item and if all items are conformant, returns a generified instance. Something like this:
              /**
                * Retrieves an unmodifiable, typed collection (a copy) of the passed-in collection if each element conforms to the type specified.
                * If one of the elements cannot be cast to the class specified, an ClassCastException is thrown
               */ 
              public <T> Collection<T> getTypedCollection(Collection<?> coll, Class<T> type) {
                 Collection<T> retList = new ArrayList<T>(col.size());
                 for ( Object o : coll ) {
                    retList.add(type.cast(o));
                 }
                 return Collections.unmodifiableCollection(retList);
              }
              
              //...usage:
              Collection<?> knownToContainStrings;
              Collection<String> stringColl = getTypedCollection(knownToContainStrings, String.class);
              A more useful library function would accept either an empty collection or a factory so that you had control over the returned collection type. Google's Guava library has a lot of good support functions for stuff like this.