8

I want to dynamically tell if an Object in Java is numeric or not. My code is as the following:

if(obj.getClass().equals(Number.class)) {
    attributeTypeStr = "Numeric";
} else {
    attributeTypeStr = "Non-Numeric";
}

The Object obj can be any numeric types like Integer, Float, Double, etc. But when I tested it with Integer/Float/Double, the attributeTypeStr always returns "Non-Numeric". I guess that's because Integer/Float/Double are subclasses of Number but Number.class does not equal Double.class. I could use something like

if(obj.getClass().equals(Integer.class) || obj.getClass().equals(Float.class) || obj.getClass().equals(Double.class))

But it looks too verbose. So is there a simple way to do that?

tonga
  • 11,749
  • 25
  • 75
  • 96

4 Answers4

15

Use instanceof:

if (obj instanceof Number)
Óscar López
  • 232,561
  • 37
  • 312
  • 386
7

Use Class#isAssignableFrom(Class) which states

Determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter.

Doing

Integer obj = new Integer(2);       
System.out.println(Number.class.isAssignableFrom(obj.getClass()));

will therefore print true.

It might not be relevant to your question, but just fyi:

Community
  • 1
  • 1
Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • While I won't dispute that this works, wouldn't instanceof Number be a simpler call to make? (Nit pick) I'd, personally, use this if I only had the Class reference, so, yes, it has its uses – MadProgrammer Sep 12 '13 at 20:06
  • @MadProgrammer Yeah, just giving options. – Sotirios Delimanolis Sep 12 '13 at 20:07
  • Wouldn't this break if type information is unavailable at runtime?(the OP's skeleton would break as well, but for future reference) – nanofarad Sep 12 '13 at 20:14
  • @SotiriosDelimanolis: This gives another option. It seems that `isAssignableFrom()` is more flexible and powerful than `instanceof`, right? – tonga Sep 12 '13 at 20:15
  • 1
    @tonga It adds possibilities. For example, if you didn't know you were trying to assign to `Number` specifically, but to the class of an Object, you could just `getClass()` on that object and call `isAssignableFrom()` on the return `Class>` instance. – Sotirios Delimanolis Sep 12 '13 at 20:17
  • @hexafraction: What situation will break this? `isAssignableFrom()` can handle class type at runtime, right? – tonga Sep 12 '13 at 20:35
  • Note that this does not work if you try to test a class object for a primitive type. For example: `Number.class.isAssignableFrom(int.class)` is false. (This does not matter if you test a value that is held in a `Object` reference of course, only when you test a class object you get from somewhere.) – Lii Oct 19 '16 at 06:36
1

Check its superclass. This works as these classes are direct superclasses:

if(obj.getClass().getSuperclass().equals(Number.class)){
    //logic
}

Or for non-direct, check Number.class.isAssignableFrom(obj.getClass()). For numeric, it shouldn't be very much of a problem as the existing Number subclasses are final. In gnerics, this may break due to the absence of type information.

nanofarad
  • 40,330
  • 4
  • 86
  • 117
1

Use isInstance() method of Class

if(Number.class.isInstance(obj)){
}

According to Class#isInstance()

Determines if the specified Object is assignment-compatible with the object represented by this Class. This method is the dynamic equivalent of the Java language instanceof operator. The method returns true if the specified Object argument is non-null and can be cast to the reference type represented by this Class object without raising a ClassCastException. It returns false otherwise.

Prabhaker A
  • 8,317
  • 1
  • 18
  • 24