Java get type arraylist

Get generic type of java.util.List

To be able to programmaticly inspect a List object and see its generic type. A method may want to insert objects based on the generic type of the collection. This is possible in languages that implement generics at runtime instead of compile time.

Right — about the only way to allow runtime detection is by sub-classing: you CAN actually extend generic type and then using reflection find type declaration that subtype used. This is quite a bit of reflection, but possible. Unfortunately there is no easy way to enforce that one must use generic sub-class.

15 Answers 15

If those are actually fields of a certain class, then you can get them with a little help of reflection:

package com.stackoverflow.q1942644; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.util.ArrayList; import java.util.List; public class Test < ListstringList = new ArrayList<>(); List integerList = new ArrayList<>(); public static void main(String. args) throws Exception < ClasstestClass = Test.class; Field stringListField = testClass.getDeclaredField("stringList"); ParameterizedType stringListType = (ParameterizedType) stringListField.getGenericType(); Class ) stringListType.getActualTypeArguments()[0]; System.out.println(stringListClass); // class java.lang.String Field integerListField = testClass.getDeclaredField("integerList"); ParameterizedType integerListType = (ParameterizedType) integerListField.getGenericType(); Class ) integerListType.getActualTypeArguments()[0]; System.out.println(integerListClass); // class java.lang.Integer > > 

You can also do that for parameter types and return type of methods.

But if they’re inside the same scope of the class/method where you need to know about them, then there’s no point of knowing them, because you already have declared them yourself.

There are certainly situations where this is above useful. In for example configurationless ORM frameworks.

You can do the same for method parameters as well:

Method method = someClass.getDeclaredMethod("someMethod"); Type[] types = method.getGenericParameterTypes(); //Now assuming that the first parameter to the method is of type List ParameterizedType pType = (ParameterizedType) types[0]; Class clazz = (Class) pType.getActualTypeArguments()[0]; System.out.println(clazz); //prints out java.lang.Integer 

This is probably a duplicate, can’t find an appropriate one right now.

Java uses something called type erasure, which means at runtime both objects are equivalent. The compiler knows the lists contain integers or strings, and as such can maintain a type safe environment. This information is lost (on an object instance basis) at runtime, and the list only contain ‘Objects’.

You CAN find out a little about the class, what types it might be parametrized by, but normally this is just anything that extends «Object», i.e. anything. If you define a type as

AClass.class will only contain the fact that the parameter A is bounded by MyClass, but more than that, there’s no way to tell.

That will be true if the concrete class of the generic is not specified; in his example, he’s explicitly declaring the lists as List and List ; in those cases, type erasure does not apply.

The generic type of a collection should only matter if it actually has objects in it, right? So isn’t it easier to just do:

Collection myCollection = getUnknownCollectionFromSomewhere(); Class genericClass = null; Iterator it = myCollection.iterator(); if (it.hasNext()) < genericClass = it.next().getClass(); >if (genericClass != null) < //do whatever we needed to know the type for 

There's no such thing as a generic type in runtime, but the objects inside at runtime are guaranteed to be the same type as the declared generic, so it's easy enough just to test the item's class before we process it.

Another thing you can do is simply process the list to get members that are the right type, ignoring others (or processing them differently).

Map, List> classObjectMap = myCollection.stream() .filter(Objects::nonNull) .collect(Collectors.groupingBy(Object::getClass)); // Process the list of the correct class, and/or handle objects of incorrect // class (throw exceptions, etc). You may need to group subclasses by // filtering the keys. For instance: List numbers = classObjectMap.entrySet().stream() .filter(e->Number.class.isAssignableFrom(e.getKey())) .flatMap(e->e.getValue().stream()) .map(Number.class::cast) .collect(Collectors.toList()); 

This will give you a list of all items whose classes were subclasses of Number which you can then process as you need. The rest of the items were filtered out into other lists. Because they're in the map, you can process them as desired, or ignore them.

If you want to ignore items of other classes altogether, it becomes much simpler:

List numbers = myCollection.stream() .filter(Number.class::isInstance) .map(Number.class::cast) .collect(Collectors.toList()); 

You can even create a utility method to insure that a list contains ONLY those items matching a specific class:

public List getTypeSafeItemList(Collection input, Class cls)

Источник

How to know if a java object is a List

PS: I have several lists of different types and would like to implement the method for any list no matter what type of data they contain.

2 Answers 2

To test if an instance is a List or an ArrayList 1 , just use instanceof .

Note that according to the JLS 15.20.2, the type operand of the instanceof operator must be a reifiable type, and that is defined in JLS 4.7 as:

  • a parameterized type in which all type arguments are unbounded wildcards,
  • a raw type
  • a primitive type (not applicable in this context
  • an array type whose element type is reifiable, or
  • a nested type where, each enclosing type is also reifiable.

So both of these should be valid:

if (obj instanceof List)) < // raw type // Do something >if (obj instanceof List )) < // type parameter is an unbounded wildcard // Do something >

but this would be a compilation error:

I have several lists of different types and would like to implement the method for any list no matter what type of data they contain.

(But it would be a problem if you wanted the method to only work for lists with certain kinds of data . based on a simple runtime typecheck. The type parameters for a generic type are not available at runtime for runtime tests, so you would need to test each element of the list individually . )

1 - Note that any ArrayList is also a List . because the ArrayList class implements the List interface.

Источник

Как получить полный тип объекта

Каким образом можно получить тип оъекта в нужном для меня формате Вот такой вариант кода у меня не сработал.

 private void invoke(String arg1, String arg2, Object dataObject) < Method[] methods = MyClass.class.getDeclaredMethods(); for (Method m : methods) < if (m.getName().equals("invoke")) < Type[] methodTypes = m.getGenericParameterTypes(); for (int i = 0; i < methodTypes.length; i++) < Log.wtf(TAG, "Check class: " + methodTypes[i]); if (methodTypes[i] instanceof ParameterizedType) < ParameterizedType t = (ParameterizedType) methodTypes[i]; Classcls = (Class) t.getActualTypeArguments()[0]; Log.d(TAG, T.class.getName() + ""); > > > > > 
java.lang.String java.lang.String java.lang.Object 

4 ответа 4

Если это поле конкретного класса, то вот так:

public class Main5 < ListstringList = new ArrayList(); List integerList = new ArrayList(); public static void main(String. args) throws Exception < Field stringListField = Main5.class.getDeclaredField("stringList"); ParameterizedType stringListType = (ParameterizedType) stringListField.getGenericType(); System.out.println(stringListType);//java.util.ListField integerListField = Main5.class.getDeclaredField("integerList"); ParameterizedType integerListType = (ParameterizedType) integerListField.getGenericType(); System.out.println(integerListType);//java.util.List > > 

Если list не пустой, то задачу можно решить с помощью получения типа одного из объектов list :

ArrayList arrayList = new ArrayList<>(); arrayList.add("Example"); System.out.println(arrayList.getClass().getName() + ""); 

UPD. Более общий случай (список может быть пустым):

public class Main < public static void main(String[] args) < ArrayListarrayList = new ArrayList<>(); someMethod(arrayList); > public static void someMethod(ArrayList arrayList) < Method[] methods = Main.class.getDeclaredMethods(); Type[] types = methods[1].getGenericParameterTypes(); ParameterizedType pType = (ParameterizedType) types[0]; Class) pType.getActualTypeArguments()[0]; System.out.println(arrayList.getClass().getName() + ""); > > 
Type[] types = methods[1].getGenericParameterTypes(); 

1 – это номер метода someMethod(. ) в классе Main .

ParameterizedType pType = (ParameterizedType) types[0]; 

0 – это номер параметра arrayList метода someMethod(. ) .

Источник

How do I find out what type each object is in a ArrayList?

I have a ArrayList made up of different elements imported from a db, made up of strings, numbers, doubles and ints. Is there a way to use a reflection type technique to find out what each type of data each element holds? FYI: The reason that there is so many types of data is that this is a piece of java code being written to be implemented with different DB's.

12 Answers 12

In C#:
Fixed with recommendation from Mike

ArrayList list = . ; // List list = . ; foreach (object o in list) < if (o is int) < HandleInt((int)o); >else if (o is string) < HandleString((string)o); >. > 
ArrayList list = . ; for (Object o : list) < if (o instanceof Integer)) < handleInt((Integer o).intValue()); >else if (o instanceof String)) < handleString((String)o); >. > 

And if you happen to be worried about every nanosecond, "as" will save you a few compared to "is" with a cast.

(int) o doesn't work in Java. It produces the error message Cannot cast from Object to int . Use (Integer o).intValue() instead.

You can use the getClass() method, or you can use instanceof. For example

Note that instanceof will match subclasses. For instance, of C is a subclass of A , then the following will be true:

C c = new C(); assert c instanceof A; 

However, the following will be false:

C c = new C(); assert !c.getClass().equals(A.class) 

don't forget about null if it is possible in your list. You'll get NullPointerExceptions from this example with nulls.

You almost never want you use something like:

Object o = . if (o.getClass().equals(Foo.class))

because you aren't accounting for possible subclasses. You really want to use Class#isAssignableFrom:

Object o = . if (Foo.class.isAssignableFrom(o))

In Java just use the instanceof operator. This will also take care of subclasses.

ArrayList listOfObjects = new ArrayList(); for(Object obj: listOfObjects)< if(obj instanceof String)< >else if(obj instanceof Integer)< >etc. > 
import java.util.ArrayList; /** * @author potter * */ public class storeAny < /** * @param args */ public static void main(String[] args) < // TODO Auto-generated method stub ArrayListanyTy=new ArrayList(); anyTy.add(new Integer(1)); anyTy.add(new String("Jesus")); anyTy.add(new Double(12.88)); anyTy.add(new Double(12.89)); anyTy.add(new Double(12.84)); anyTy.add(new Double(12.82)); for (Object o : anyTy) < if(o instanceof String)< System.out.println(o.toString()); >else if(o instanceof Integer) < System.out.println(o.toString()); >else if(o instanceof Double) < System.out.println(o.toString()); >> > > 

Just call .getClass() on each Object in a loop.

Unfortunately, Java doesn't have map() . 🙂

Instanceof works if you don't depend on specific classes, but also keep in mind that you can have nulls in the list, so obj.getClass() will fail, but instanceof always returns false on null.

instead of using object.getClass().getName() you can use object.getClass().getSimpleName() , because it returns a simple class name without a package name included.

Object[] intArray = < 1 >; for (Object object : intArray)

You say "this is a piece of java code being written", from which I infer that there is still a chance that you could design it a different way.

Having an ArrayList is like having a collection of stuff. Rather than force the instanceof or getClass every time you take an object from the list, why not design the system so that you get the type of the object when you retrieve it from the DB, and store it into a collection of the appropriate type of object?

Or, you could use one of the many data access libraries that exist to do this for you.

Источник

Читайте также:  Split screen in 2 html
Оцените статью