56

Is there a "typeof" like function in Java that returns the type of a primitive data type (PDT) variable or an expression of operands PDTs?

instanceof seems to work for class types only.

nbro
  • 15,395
  • 32
  • 113
  • 196
ashley
  • 1,177
  • 1
  • 14
  • 17
  • 1
    Are you looking for a `Class` that represents `int`, `long` and so on? – Sergey Kalinichenko Sep 11 '12 at 01:23
  • 3
    You can't have a primitive data type without knowing the type of it. It would have to be boxed in to a `Number` type in order for you not to know it, in which case you can use `instanceof`. – Vala Sep 11 '12 at 01:25
  • @Thor84no yeah you can with reflection – Bohemian Sep 11 '12 at 01:47
  • @Bohemian I think reflection also uses wrapper classes automatically, though I haven't tested it. – Vala Sep 11 '12 at 01:49
  • 1
    Possible duplicate of [Determining if an Object is of primitive type](http://stackoverflow.com/questions/709961/determining-if-an-object-is-of-primitive-type) – Abhijeet Aug 15 '16 at 05:48

4 Answers4

85

Try the following:

int i = 20;
float f = 20.2f;
System.out.println(((Object)i).getClass().getName());
System.out.println(((Object)f).getClass().getName());

It will print:

java.lang.Integer
java.lang.Float

As for instanceof, you could use its dynamic counterpart Class#isInstance:

Integer.class.isInstance(20);  // true
Integer.class.isInstance(20f); // false
Integer.class.isInstance("s"); // false
João Silva
  • 89,303
  • 29
  • 152
  • 158
  • 4
    unfortunately, that's not the primitive type. that's just the boxed type. – dtc Mar 12 '20 at 17:55
  • 3
    @dtc It works transitively and I have yet to find an instance where it does not work. It works for boolean even. So if object can box up your primitive correctly every time then what's the difference? – chrips Dec 27 '20 at 18:51
  • Very clever, thanks! :D – Makc Mar 15 '22 at 16:49
23

There's an easy way that doesn't necessitate the implicit boxing, so you won't get confused between primitives and their wrappers. You can't use isInstance for primitive types -- e.g. calling Integer.TYPE.isInstance(5) (Integer.TYPE is equivalent to int.class) will return false as 5 is autoboxed into an Integer before hand.

The easiest way to get what you want (note - it's technically done at compile-time for primitives, but it still requires evaluation of the argument) is via overloading. See my ideone paste.

...

public static Class<Integer> typeof(final int expr) {
  return Integer.TYPE;
}

public static Class<Long> typeof(final long expr) {
  return Long.TYPE;
}

...

This can be used as follows, for example:

System.out.println(typeof(500 * 3 - 2)); /* int */
System.out.println(typeof(50 % 3L)); /* long */

This relies on the compiler's ability to determine the type of the expression and pick the right overload.

obataku
  • 29,212
  • 3
  • 44
  • 57
2

You can use the following class.

class TypeResolver
{
    public static String Long = "long";
    public static String Int = "int";
    public static String Float = "float";
    public static String Double = "double";
    public static String Char = "char";
    public static String Boolean = "boolean";
    public static String Short = "short";
    public static String Byte = "byte";

    public static void main(String[] args)
    {
        //all true
        TypeResolver resolver = new TypeResolver();
        System.out.println(resolver.getType(1) == TypeResolver.Int); 
        System.out.println(resolver.getType(1f) == TypeResolver.Float); 
        System.out.println(resolver.getType(1.0) == TypeResolver.Double);
        System.out.println(resolver.getType('a') == TypeResolver.Char); 
        System.out.println(resolver.getType((short) 1) == TypeResolver.Short); 
        System.out.println(resolver.getType((long) 1000) == TypeResolver.Long);
        System.out.println(resolver.getType(false) == TypeResolver.Boolean); 
        System.out.println(resolver.getType((byte) 2) == TypeResolver.Byte);
    }

    public String getType(int x)
    {
        return TypeResolver.Int;
    }

    public String getType(byte x)
    {
        return TypeResolver.Byte;
    }

    public String getType(float x)
    {
        return TypeResolver.Float;
    }

    public String getType(double x)
    {
        return TypeResolver.Double;
    }

    public String getType(boolean x)
    {
        return TypeResolver.Boolean;
    }

    public String getType(short x)
    {
        return TypeResolver.Short;
    }

    public String getType(long x)
    {
        return TypeResolver.Long;
    }

    public String getType(char x)
    {
        return TypeResolver.Char;
    }
}
Douma
  • 2,682
  • 14
  • 23
  • That's pretty ingenious considering you are using function overloading to do the task for you. – BEWARB Dec 13 '19 at 11:14
  • just calling out for the downsides: it will need a steady watch out for new additions - and thus will not cover "new" items automatically. - maintaining coding language infrastructure services is a thing rather being resolved in the realm of the language developers. thus forth developing the language itself will not have extra impacts on existing project codes. by doing so any code using the related environmental features will instantly profit on such features just when compiled/interpreted next. – Alexander Stohr Jan 28 '21 at 13:51
  • This is essentially the same answer as what obataku gave 8 years earlier, except that obataku reuses `Class<>.TYPE` instead of defining all the type names again. So actually this answer is not as elegant. – trincot Jun 19 '21 at 20:19
0

There are two ways that you can use to determine the type of the Primitive type.

package com.company;

public class Testing {
public static void main(String[] args) {
    int x;
    x=0;
    // the first method 
    System.out.println(((Object)x).getClass().getName());
    if (((Object)x).getClass().getName()=="java.lang.Integer")
        System.out.println("i am int");
   // the second method it will either return true or false
    System.out.println(Integer.class.isInstance(x));
}

}

AlixaProDev
  • 472
  • 1
  • 5
  • 13