Reputation: 1353
I have an Object[]
array, and I am trying to find the ones that are primitives. I've tried to use Class.isPrimitive()
, but it seems I'm doing something wrong:
int i = 3;
Object o = i;
System.out.println(o.getClass().getName() + ", " +
o.getClass().isPrimitive());
prints java.lang.Integer, false
.
Is there a right way or some alternative?
Upvotes: 132
Views: 147930
Reputation: 27677
Google's Guava library has a Primitives utility that check if a class is a wrapper type for a primitive: Primitives.isWrapperType(class)
.
Class.isPrimitive()
works for primitives
Upvotes: 27
Reputation: 176
For users of javapoet, there's also this way:
private boolean isBoxedPrimitive(Class<?> type) {
return TypeName.get(type).isBoxedPrimitive();
}
Upvotes: 0
Reputation: 1500215
The types in an Object[]
will never really be primitive - because you've got references! Here the type of i
is int
whereas the type of the object referenced by o
is Integer
(due to auto-boxing).
It sounds like you need to find out whether the type is a "wrapper for primitive". I don't think there's anything built into the standard libraries for this, but it's easy to code up:
import java.util.*;
public class Test
{
public static void main(String[] args)
{
System.out.println(isWrapperType(String.class));
System.out.println(isWrapperType(Integer.class));
}
private static final Set<Class<?>> WRAPPER_TYPES = getWrapperTypes();
public static boolean isWrapperType(Class<?> clazz)
{
return WRAPPER_TYPES.contains(clazz);
}
private static Set<Class<?>> getWrapperTypes()
{
Set<Class<?>> ret = new HashSet<Class<?>>();
ret.add(Boolean.class);
ret.add(Character.class);
ret.add(Byte.class);
ret.add(Short.class);
ret.add(Integer.class);
ret.add(Long.class);
ret.add(Float.class);
ret.add(Double.class);
ret.add(Void.class);
return ret;
}
}
Upvotes: 174
Reputation: 597076
commons-lang ClassUtils
has relevant methods.
The new version has:
boolean isPrimitiveOrWrapped =
ClassUtils.isPrimitiveOrWrapper(object.getClass());
The old versions have wrapperToPrimitive(clazz)
method, which will return the primitive correspondence.
boolean isPrimitiveOrWrapped =
clazz.isPrimitive() || ClassUtils.wrapperToPrimitive(clazz) != null;
Upvotes: 104
Reputation: 63
public static boolean isValidType(Class<?> retType)
{
if (retType.isPrimitive() && retType != void.class) return true;
if (Number.class.isAssignableFrom(retType)) return true;
if (AbstractCode.class.isAssignableFrom(retType)) return true;
if (Boolean.class == retType) return true;
if (Character.class == retType) return true;
if (String.class == retType) return true;
if (Date.class.isAssignableFrom(retType)) return true;
if (byte[].class.isAssignableFrom(retType)) return true;
if (Enum.class.isAssignableFrom(retType)) return true;
return false;
}
Upvotes: 6
Reputation: 11
you could determine if an object is wrapper type by beneath statements:
***objClass.isAssignableFrom(Number.class);***
and you could also determine a primitive object by using the isPrimitive() method
Upvotes: 1
Reputation: 3893
I'm late to the show, but if you're testing a field, you can use getGenericType
:
import static org.junit.Assert.*;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import org.junit.Test;
public class PrimitiveVsObjectTest {
private static final Collection<String> PRIMITIVE_TYPES =
new HashSet<>(Arrays.asList("byte", "short", "int", "long", "float", "double", "boolean", "char"));
private static boolean isPrimitive(Type type) {
return PRIMITIVE_TYPES.contains(type.getTypeName());
}
public int i1 = 34;
public Integer i2 = 34;
@Test
public void primitive_type() throws NoSuchFieldException, SecurityException {
Field i1Field = PrimitiveVsObjectTest.class.getField("i1");
Type genericType1 = i1Field.getGenericType();
assertEquals("int", genericType1.getTypeName());
assertNotEquals("java.lang.Integer", genericType1.getTypeName());
assertTrue(isPrimitive(genericType1));
}
@Test
public void object_type() throws NoSuchFieldException, SecurityException {
Field i2Field = PrimitiveVsObjectTest.class.getField("i2");
Type genericType2 = i2Field.getGenericType();
assertEquals("java.lang.Integer", genericType2.getTypeName());
assertNotEquals("int", genericType2.getTypeName());
assertFalse(isPrimitive(genericType2));
}
}
The Oracle docs list the 8 primitive types.
Upvotes: 2
Reputation: 1884
Get ahold of BeanUtils from Spring http://static.springsource.org/spring/docs/3.0.x/javadoc-api/
Probably the Apache variation (commons beans) has similar functionality.
Upvotes: 1
Reputation: 5082
This is the simplest way I could think of. The wrapper classes are present only in java.lang
package. And apart from the wrapper classes, no other class in java.lang
has field named TYPE
. You could use that to check whether a class is Wrapper class or not.
public static boolean isBoxingClass(Class<?> clazz)
{
String pack = clazz.getPackage().getName();
if(!"java.lang".equals(pack))
return false;
try
{
clazz.getField("TYPE");
}
catch (NoSuchFieldException e)
{
return false;
}
return true;
}
Upvotes: 1
Reputation: 2102
public class CheckPrimitve {
public static void main(String[] args) {
int i = 3;
Object o = i;
System.out.println(o.getClass().getSimpleName().equals("Integer"));
Field[] fields = o.getClass().getFields();
for(Field field:fields) {
System.out.println(field.getType());
}
}
}
Output:
true
int
int
class java.lang.Class
int
Upvotes: 0
Reputation: 1658
Starting in Java 1.5 and up, there is a new feature called auto-boxing. The compiler does this itself. When it sees an opportunity, it converts a primitive type into its appropriate wrapper class.
What is probably happening here is when you declare
Object o = i;
The compiler will compile this statement as saying
Object o = Integer.valueOf(i);
This is auto-boxing. This would explain the output you are receiving. This page from the Java 1.5 spec explains auto-boxing more in detail.
Upvotes: 9
Reputation: 61526
Just so you can see that is is possible for isPrimitive to return true (since you have enough answers showing you why it is false):
public class Main
{
public static void main(final String[] argv)
{
final Class clazz;
clazz = int.class;
System.out.println(clazz.isPrimitive());
}
}
This matters in reflection when a method takes in "int" rather than an "Integer".
This code works:
import java.lang.reflect.Method;
public class Main
{
public static void main(final String[] argv)
throws Exception
{
final Method method;
method = Main.class.getDeclaredMethod("foo", int.class);
}
public static void foo(final int x)
{
}
}
This code fails (cannot find the method):
import java.lang.reflect.Method;
public class Main
{
public static void main(final String[] argv)
throws Exception
{
final Method method;
method = Main.class.getDeclaredMethod("foo", Integer.class);
}
public static void foo(final int x)
{
}
}
Upvotes: 3
Reputation: 533492
For those who like terse code.
private static final Set<Class> WRAPPER_TYPES = new HashSet(Arrays.asList(
Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class, Float.class, Double.class, Void.class));
public static boolean isWrapperType(Class clazz) {
return WRAPPER_TYPES.contains(clazz);
}
Upvotes: 21
Reputation: 57284
The primitve wrapper types will not respond to this value. This is for class representation of primitives, though aside from reflection I can't think of too many uses for it offhand. So, for example
System.out.println(Integer.class.isPrimitive());
prints "false", but
public static void main (String args[]) throws Exception
{
Method m = Junk.class.getMethod( "a",null);
System.out.println( m.getReturnType().isPrimitive());
}
public static int a()
{
return 1;
}
prints "true"
Upvotes: 3
Reputation: 684
You have to deal with the auto-boxing of java.
Let's take the code
public class test { public static void main(String [ ] args) { int i = 3; Object o = i; return; } }You get the class test.class and javap -c test let's you inspect the generated bytecode.
Compiled from "test.java" public class test extends java.lang.Object{ public test(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."":()V 4: returnAs you can see the java compiler addedpublic static void main(java.lang.String[]); Code: 0: iconst_3 1: istore_1 2: iload_1 3: invokestatic #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; 6: astore_2 7: return
}
invokestatic #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;to create a new Integer from your int and then stores that new Object in o via astore_2
Upvotes: 4
Reputation: 48265
I think this happens due to auto-boxing.
int i = 3;
Object o = i;
o.getClass().getName(); // prints Integer
You may implement a utility method that matches these specific boxing classes and gives you if a certain class is primitive.
public static boolean isWrapperType(Class<?> clazz) {
return clazz.equals(Boolean.class) ||
clazz.equals(Integer.class) ||
clazz.equals(Character.class) ||
clazz.equals(Byte.class) ||
clazz.equals(Short.class) ||
clazz.equals(Double.class) ||
clazz.equals(Long.class) ||
clazz.equals(Float.class);
}
Upvotes: 7
Reputation: 191875
As several people have already said, this is due to autoboxing.
You could create a utility method to check whether the object's class is Integer
, Double
, etc. But there is no way to know whether an object was created by autoboxing a primitive; once it's boxed, it looks just like an object created explicitly.
So unless you know for sure that your array will never contain a wrapper class without autoboxing, there is no real solution.
Upvotes: 2