201

Let's say I declare a variable:

String a = "test";

And I want to know what type it is, i.e., the output should be java.lang.String How do I do this?

Ojonugwa Jude Ochalifu
  • 26,627
  • 26
  • 120
  • 132
Miguel Ribeiro
  • 8,057
  • 20
  • 51
  • 74
  • 3
    Are you really interested in the *type of the variable*? Or do you care about the *type of the value*? Because the type of the variable can't easily be gotten (in fact it's not possible at all for local variables and requires reflection for fields). – Joachim Sauer Apr 20 '10 at 11:23
  • @Joachim, what exactly is the difference between "type of the variable" and "type of the value"? – Paul Tomblin Apr 20 '10 at 11:31
  • 9
    @Paul: Consider `Object o = "o";` - the type of the variable is Object, the type of the value is String. – Michael Borgwardt Apr 20 '10 at 12:02
  • 2
    @Paul In `List l = new ArrayList();`, the type of the variable is `List`, the type of the value is `ArrayList`. – Ben Lings Apr 20 '10 at 12:04
  • 1
    @Ben Lings The type of variable is java.util.ArrayList and the type of value is java.util.ArrayList. – Ajay Takur Oct 17 '13 at 08:37
  • 2
    @AjayThakur - it's the difference between the compile-time (static) type and the runtime (dynamic) type. – Ben Lings Oct 17 '13 at 09:10

7 Answers7

367
a.getClass().getName()
Martin
  • 37,119
  • 15
  • 73
  • 82
  • 25
    That will give the type of the value. not necessarily the type of the variable. – Joachim Sauer Apr 20 '10 at 11:18
  • 7
    I just figured that was what the OP was really looking for since the declaration of `a` is pretty obvious at compile time – Martin Apr 20 '10 at 11:22
  • 5
    That would work if the types aren't primitives... If the type is int , how to know the type? – Miguel Ribeiro Apr 20 '10 at 11:32
  • 6
    @Miguel: since the only way you can handle an `int` value is in an `int` variable, there's no way to write code that handles a `int` value and **doesn't** know that type. The matter is different in case you're handling a wrapper like `Integer`, but then the code of this answer works again. – Joachim Sauer Apr 20 '10 at 14:12
  • 2
    this is not true for a primitive type. – Mehdi Aug 21 '15 at 02:17
  • I come from ruby and wanted to test: Integer.parseInt("12").getClass().getName() which evidently does not work. No idea if anyone reads this, but a universal type query method would be great. (I was trying to determine the difference between .valueOf() and .parse* related methods.) – shevy Mar 25 '20 at 23:57
  • @shevy `Integer.parseInt()` return primitive int type, not an instance of Integer class. Instead, `(Object Integer.parseInt("12")) wraps the int into an Integer object, which inherits the method `getClass()` from `Object`. – Yossarian42 Jul 31 '20 at 12:36
  • this is not given for primitive type varibales – pradeep karunathilaka Nov 09 '20 at 04:43
  • but this fails for a null value :( – newbie Jul 15 '21 at 12:57
56

Expanding on Martin's answer...

Martins Solution

a.getClass().getName()

Expanded Solution

If you want it to work with anything you can do this:

((Object) myVar).getClass().getName()
//OR
((Object) myInt).getClass().getSimpleName()

In case of a primitive type, it will be wrapped (Autoboxed) in a corresponding Object variant.

Example #1 (Regular)

private static String nameOf(Object o) {
    return o.getClass().getSimpleName();
}

Example #2 (Generics)

public static <T> String nameOf(T o) {
    return o.getClass().getSimpleName();
}

Additional Learning

Atspulgs
  • 1,359
  • 11
  • 9
  • Interesting. I just tried your code on: System.out.println( ( (Object) Integer.parseInt("12") ).getClass().getSimpleName() ); and it works! \o/ – shevy Mar 25 '20 at 23:59
  • Thank you very much, before the `getSimpleName()`, I tried to use `(Stack)(variable.getClass().toString().split(".")).pop()` and it didn't work, I was using JavaScript logic and type casted it into stack to pop the last element after spliting with `.` and it didn't work. – 27px Dec 25 '20 at 13:25
  • I have a little problem with my code. The last condition below is supposed to return true, but it doesn't. The variable result is a double and equal to 2.5. I tried to figure out how to fix it with this piece of code – Sergey Zolotarev Dec 21 '22 at 13:13
  • System.out.println("Result is: " + result); System.out.println("The datatype of result is: " + result.getClass().getName()); System.out.println("String.valueOf(result) is: " + String.valueOf(result)); System.out.println("The datatype of result is: " + String.valueOf(result).getClass().getName()); System.out.println("df.format(result) is: " + df.format(result)); System.out.println("The datatype of result is: " + df.format(result).getClass().getName()); – Sergey Zolotarev Dec 21 '22 at 13:13
  • System.out.println("Is String.valueOf(result) equal to df.format(result): " + String.valueOf(result).equals(df.format(result))); However, my IntelliJ IDEA "cannot resolve method 'getClass()'" when applied to result directly (the second line of the code). Could you tell me please why that's so? – Sergey Zolotarev Dec 21 '22 at 13:14
  • Are you sure your variable is a Wrapper? (an object and not a primitive) You cannot call class methods on primitives, you need to wrap them in the corresponding wrappers beforehand. Thats what this is for: ((Object) myVar).getClass() – Atspulgs Dec 22 '22 at 17:51
46

If you want the name, use Martin's method. If you want to know whether it's an instance of a certain class:

boolean b = a instanceof String

Martin Konecny
  • 57,827
  • 19
  • 139
  • 159
34

I learned from the Search Engine(My English is very bad , So code...) How to get variable's type? Up's :

String str = "test";
String type = str.getClass().getName();
value: type = java.lang.String

this method :

str.getClass().getSimpleName();
value:String

now example:

Object o = 1;
o.getClass().getSimpleName();
value:Integer
Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
Copy_Paste
  • 341
  • 3
  • 3
4

Use operator overloading feature of java

class Test {

    void printType(String x) {
        System.out.print("String");
    }

    void printType(int x) {     
        System.out.print("Int");
    }

    // same goes on with boolean,double,float,object ...

}
Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
4

I think we have multiple solutions here:

  • instance of could be a solution.

Why? In Java every class is inherited from the Object class itself. So if you have a variable and you would like to know its type. You can use

  • System.out.println(((Object)f).getClass().getName());

or

  • Integer.class.isInstance(1985); // gives true

or

  • isPrimitive()

    public static void main(String[] args) {
    
     ClassDemo classOne = new ClassDemo();
     Class classOneClass = classOne();
    
     int i = 5;
     Class iClass = int.class;
    
     // checking for primitive type
     boolean retval1 = classOneClass.isPrimitive();
     System.out.println("classOneClass is primitive type? = " + retval1);
    
     // checking for primitive type?
     boolean retval2 = iClass.isPrimitive();
     System.out.println("iClass is primitive type? = " + retval2);
    }
    

This going to give us:

  1. FALSE
  2. TRUE

Find out more here: How to determine the primitive type of a primitive variable?

https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

http://docs.oracle.com/cd/E26806_01/wlp.1034/e14255/com/bea/p13n/expression/operator/Instanceof.html

Arun Joseph
  • 2,736
  • 25
  • 35
narancs
  • 5,234
  • 4
  • 41
  • 60
3

I agree with what Joachim Sauer said, not possible to know (the variable type! not value type!) unless your variable is a class attribute (and you would have to retrieve class fields, get the right field by name...)

Actually for me it's totally impossible that any a.xxx().yyy() method give you the right answer since the answer would be different on the exact same object, according to the context in which you call this method...

As teehoo said, if you know at compile a defined list of types to test you can use instanceof but you will also get subclasses returning true...

One possible solution would also be to inspire yourself from the implementation of java.lang.reflect.Field and create your own Field class, and then declare all your local variables as this custom Field implementation... but you'd better find another solution, i really wonder why you need the variable type, and not just the value type?

Andrii Abramov
  • 10,019
  • 9
  • 74
  • 96
Sebastien Lorber
  • 89,644
  • 67
  • 288
  • 419
  • For _"but you will also get subclasses returning true..."_, I think you meant _"but you will also get parent classes returning true..."_, right? – skomisa Mar 25 '18 at 06:33