175

How can I check to make sure my variable is an int, array, double, etc...?

Edit: For example, how can I check that a variable is an array? Is there some function to do this?

Strawberry
  • 66,024
  • 56
  • 149
  • 197
  • 1
    Take a look to the [Reflection API](http://download.oracle.com/javase/tutorial/reflect/). – Martín Schonaker Oct 22 '10 at 05:17
  • 1
    Very related question with answers here: https://stackoverflow.com/questions/2674554/how-do-you-know-a-variable-type-in-java. – A.Alessio May 27 '20 at 08:02
  • Does this answer your question? [How do you know a variable type in java?](https://stackoverflow.com/questions/2674554/how-do-you-know-a-variable-type-in-java) – Leponzo Apr 03 '21 at 04:18

17 Answers17

139

Java is a statically typed language, so the compiler does most of this checking for you. Once you declare a variable to be a certain type, the compiler will ensure that it is only ever assigned values of that type (or values that are sub-types of that type).

The examples you gave (int, array, double) these are all primitives, and there are no sub-types of them. Thus, if you declare a variable to be an int:

int x;

You can be sure it will only ever hold int values.

If you declared a variable to be a List, however, it is possible that the variable will hold sub-types of List. Examples of these include ArrayList, LinkedList, etc.

If you did have a List variable, and you needed to know if it was an ArrayList, you could do the following:

List y;
...
if (y instanceof ArrayList) { 
  ...its and ArrayList...
}

However, if you find yourself thinking you need to do that, you may want to rethink your approach. In most cases, if you follow object-oriented principles, you will not need to do this. There are, of course, exceptions to every rule, though.

Skylar
  • 928
  • 5
  • 18
pkaeding
  • 36,513
  • 30
  • 103
  • 141
  • 5
    The instanceof operator only determines the datatype of the object referred to by the variable. It does not determine the datatype of the actual VARIABLE as originally requested. – GrantRobertson Jul 25 '16 at 04:16
  • 1
    This does not answer the question effectively. Glen Pierce's, `a.getClass().getName()` IMO, should be the accepted answer. – ctpenrose Apr 07 '23 at 20:41
53

Actually quite easy to roll your own tester, by abusing Java's method overload ability. Though I'm still curious if there is an official method in the sdk.

Example:

class Typetester {
    void printType(byte x) {
        System.out.println(x + " is an byte");
    }
    void printType(int x) {
        System.out.println(x + " is an int");
    }
    void printType(float x) {
        System.out.println(x + " is an float");
    }
    void printType(double x) {
        System.out.println(x + " is an double");
    }
    void printType(char x) {
        System.out.println(x + " is an char");
    }
}

then:

Typetester t = new Typetester();
t.printType( yourVariable );
Mvcoile
  • 719
  • 5
  • 3
  • 32
    Not a good method IMO. What happens if I pass some arbitrary type that is not defined in your Typetester class - in this instance String, for example? – Tash Pemhiwa Oct 07 '13 at 14:16
  • 11
    @TashPemhiwa then add String and Object to the choices. Creativity and problem solving are a programmers best assets. – Kato Oct 01 '14 at 18:22
  • 15
    Still this can only deal with a fixed set of pre-defined classes (which defeats the purpose of object orientation/polymorphism) and will only give you something like "unknown class" for objects of any other class – Algoman Nov 05 '15 at 10:24
  • 3
    The choice of which signature happens at compile time, not runtime. So this technique won't tell you anything you don't already know at compile time. https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2 – jmh Jun 30 '17 at 20:31
  • 1
    @Algoman getting something like “unknown class” wouldn’t be the worst thing. The worst thing is to get wrong answers, e.g. when trying `short x = 42; printType(x);` In fact, if someone adds a “helpful” `void printType(Object x)` overload there won’t be any “unknown class” results at all, but only potentially wrong results… – Holger May 31 '23 at 09:10
41

a.getClass().getName() - will give you the datatype of the actual object referred to by a, but not the datatype that the variable a was originally declared as or subsequently cast to.

boolean b = a instanceof String - will give you whether or not the actual object referred to by a is an instance of a specific class. Again, the datatype that the variable a was originally declared as or subsequently cast to has no bearing on the result of the instanceof operator.

I took this information from: How do you know a variable type in java?

This can happen. I'm trying to parse a String into an int and I'd like to know if my Integer.parseInt(s.substring(a, b)) is kicking out an int or garbage before I try to sum it up.

By the way, this is known as Reflection. Here's some more information on the subject: http://docs.oracle.com/javase/tutorial/reflect/

Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
Glen Pierce
  • 4,401
  • 5
  • 31
  • 50
33

Just use:

.getClass().getSimpleName();

Example:

StringBuilder randSB = new StringBuilder("just a String");
System.out.println(randSB.getClass().getSimpleName());

Output:

StringBuilder
anothernode
  • 5,100
  • 13
  • 43
  • 62
Debayan
  • 459
  • 4
  • 6
16

You may work with Integer instead of int, Double instead of double, etc. (such classes exists for all primitive types). Then you may use the operator instanceof, like if(var instanceof Integer){...}

Chanakya
  • 178
  • 1
  • 16
Alex Abdugafarov
  • 6,112
  • 7
  • 35
  • 59
9

Well, I think checking the type of variable can be done this way.

public <T extends Object> void checkType(T object) {    
    if (object instanceof Integer)
        System.out.println("Integer ");
    else if(object instanceof Double)
        System.out.println("Double ");
    else if(object instanceof Float)
        System.out.println("Float : ");
    else if(object instanceof List)
        System.out.println("List! ");
    else if(object instanceof Set)
        System.out.println("Set! ");
}

This way you need not have multiple overloaded methods. I think it is good practice to use collections over arrays due to the added benefits. Having said that, I do not know how to check for an array type. Maybe someone can improve this solution. Hope this helps!

P.S Yes, I know that this doesn't check for primitives as well.

Massimiliano Kraus
  • 3,638
  • 5
  • 27
  • 47
Amogh
  • 99
  • 1
  • 4
6

I did it using: if(x.getClass() == MyClass.class){...}

hkutluay
  • 6,794
  • 2
  • 33
  • 53
6

The first part of your question is meaningless. There is no circumstance in which you don't know the type of a primitive variable at compile time.

Re the second part, the only circumstance that you don't already know whether a variable is an array is if it is an Object. In which case object.getClass().isArray() will tell you.

hkutluay
  • 6,794
  • 2
  • 33
  • 53
user207421
  • 305,947
  • 44
  • 307
  • 483
  • 5
    I could have a hashmap from string to object, put an int in that hashmap, and pull it back out. Only thing I know is that it's an "object" and could have to check for what type it is. Not saying it's good, just saying it's possible. – matty-d Nov 27 '13 at 00:26
  • 1
    @matty-d the scenario you describe, is about the *type of the object*, not the type of a variable. In that regard, I would even say that the scenario of a variable of type `Object` referring to an array instance, is meaningless, as the *type of the variable* still is `Object`. Ironically, things have changed in the meanwhile, as nowadays you can declare variables with `var` and indeed not know what type the variable has. But, of course, the right way to deal with this, is not to use `var` when the type is unclear, not to try to find out the type after the fact. – Holger May 31 '23 at 09:30
4

I wasn't happy with any of these answers, and the one that's right has no explanation and negative votes so I searched around, found some stuff and edited it so that it is easy to understand. Have a play with it, not as straight forward as one would hope.

//move your variable into an Object type
Object obj=whatYouAreChecking;
System.out.println(obj);

// moving the class type into a Class variable
Class cls=obj.getClass();
System.out.println(cls);

// convert that Class Variable to a neat String
String answer = cls.getSimpleName();
System.out.println(answer);

Here is a method:

public static void checkClass (Object obj) {
    Class cls = obj.getClass();
    System.out.println("The type of the object is: " + cls.getSimpleName());       
}
Neil Regan
  • 153
  • 1
  • 5
  • works with primitive types as well but it lists "Integer" for a regular integer. – JohnP2 Dec 07 '22 at 22:34
  • 1
    This prints the type of the object but not the type of the variable. This is best illustrated by the fact that the variable `obj` has type `Object` and when the caller doesn’t have a variable at all, e.g. `checkClass("foo")`, that variable of type `Object` is the only variable around and still, the method will print “`String`”. – Holger May 31 '23 at 09:14
4

Basically , For example :

public class Kerem
{
    public static void main(String[] args)
    {
        short x = 10;
        short y = 3;
        Object o = y;
        System.out.println(o.getClass()); // java.lang.Short
    }

}
Doktor
  • 73
  • 2
  • 6
1

None of these answers work if the variable is an uninitialized generic type

And from what I can find, it's only possible using an extremely ugly workaround, or by passing in an initialized parameter to your function, making it in-place, see here:

<T> T MyMethod(...){ if(T.class == MyClass.class){...}}

Is NOT valid because you cannot pull the type out of the T parameter directly, since it is erased at runtime time.

<T> void MyMethod(T out, ...){ if(out.getClass() == MyClass.class){...}}

This works because the caller is responsible to instantiating the variable out before calling. This will still throw an exception if out is null when called, but compared to the linked solution, this is by far the easiest way to do this

I know this is a kind of specific application, but since this is the first result on google for finding the type of a variable with java (and given that T is a kind of variable), I feel it should be included

iggy12345
  • 1,233
  • 12
  • 31
1

I hit this question as I was trying to get something similar working using Generics. Taking some of the answers and adding getClass().isArray() I get the following that seems to work.

public class TypeTester <T extends Number>{

<T extends Object> String tester(T ToTest){

    if (ToTest instanceof Integer) return ("Integer");
    else if(ToTest instanceof Double) return ("Double");
    else if(ToTest instanceof Float) return ("Float");
    else if(ToTest instanceof String) return ("String");
    else if(ToTest.getClass().isArray()) return ("Array");
    else return ("Unsure");
}
}

I call it with this where the myArray part was simply to get an Array into callFunction.tester() to test it.

public class Generics {
public static void main(String[] args) {
    int [] myArray = new int [10];

    TypeTester<Integer> callFunction = new TypeTester<Integer>();
    System.out.println(callFunction.tester(myArray));
}
}

You can swap out the myArray in the final line for say 10.2F to test Float etc

SlinnShady
  • 435
  • 4
  • 10
1
var.getClass().getSimpleName()

Let's take a example

String[] anArrayOfStrings = { "Agra", "Mysore", "Chandigarh", "Bhopal" };
List<String> strList = Arrays.asList(anArrayOfStrings); 

anArrayOfStrings.getClass().getSimpleName() //res =>  String[]
strList.getClass().getSimpleName() // res => ArrayList
Parth kharecha
  • 6,135
  • 4
  • 25
  • 41
0

You can check it easily using Java.lang.Class.getSimpleName() Method Only if variable has non-primitive type. It doesnt work with primitive types int ,long etc.

reference - Here is the Oracle docs link

GeekyCoder
  • 138
  • 11
  • Thanks for the hint. I was focusing on the type/array checking example, though, not what to do within the logic. – fozzybear Mar 28 '23 at 17:46
  • Correction: I thought you'd answered to my example, where `getSimpleName()` actually works as intended. I'd second checking types against Strings. For this, I'd recommend `instanceof` and `getClass().isAssignableFrom()`, as shown above. If you have primitives, then there's no need for checking - if you've got boxed Objects, use `i instanceof Integer` and similar instead, or, for only numbers `n instanceof Number`. – fozzybear Mar 30 '23 at 12:19
0
public static void chkType(Object var){     
        String type = var.getClass().toString();
        System.out.println(type.substring(16));     
        //assertEquals(type,"class java.lang.Boolean");
        //assertEquals(type,"class java.lang.Character");
        //assertEquals(type,"class java.lang.Integer");
        //assertEquals(type,"class java.lang.Double");      
    }
  • This prints the data type but does not answer the question. Where is the check for array? – Queeg Mar 07 '21 at 06:43
0

A simple solution I found was the following rather than wondering about fire command. Also, you can check this article

public class DataTypeCheck 
{

    public static void main(String[] args)
    {
        String jobTitle = "Agent";
        int employeeId = 7;
        double floating= 10.0;
        String bond = jobTitle + employeeId;

        System.out.println(((Object)floating).getClass().getSimpleName());
        System.out.println(((Object)employeeId).getClass().getSimpleName());
        System.out.println(((Object)jobTitle).getClass().getSimpleName());
        System.out.println(((Object)bond).getClass().getSimpleName());
    }

}
Output:
Double
Integer
String
String
code_conundrum
  • 529
  • 6
  • 12
0

An Object instance can be type-tested in several ways and for array properties by checking its Class type like this:

public static <T> void typetest(final T t) {
 if (t != null) {
  
  final Class<? extends Object> clazz = t.getClass();
  // Check is an Object is an array 
  if (clazz.isArray()) {
    // Shows array Object type
    System.out.println("Is array of type: [" + clazz.getSimpleName() + "]");
  }
  
  // Check is an Object is an array / get a non-null result array class for array Object types 
  final Class<?> ct = clazz.getComponentType();
  if (ct != null) {
    // Shows array primitive/Object type
    if (ct.isPrimitive()) {
      System.out.println("Primitive array of type: [" + ct.getSimpleName() + "]");
    } else {
      System.out.println("Array of Object type: [" + ct.getSimpleName() + "]");
    }
  }
  
  // Since Java 12 there's also 
  final Class<?> arrayType = ct.arrayType();
  
  // Matches a Objects are instances of List 
  if (t instanceof List) {
    // ...
  // Matches a Objects are instances of Collection (i. e. List, Set...) 
  } else if (t instanceof Collection) {
    // ...
  // Matches a Objects are instances of Map (i. e. List, Set...) 
  } else if (t instanceof Map) {
  }
  
  // Matches all Objects that have List as superclass or implement interface 
  if (List.class.getClass().isAssignableFrom(clazz)) {
    // ...
  // Matches all Objects that have Collection as superclass or implement interface 
  } else if (Collection.class.getClass().isAssignableFrom(clazz)) {
    // ...
  // Matches all Objects that have Map as superclass or implement interface 
  } else if (Map.class.getClass().isAssignableFrom(clazz)) {
    // ...
  }
 }
}

Note, that it's possible to check against specific types and implemented interfaces or inheritance from superclasses with isAssignableFrom().

If an Object was wrapped or cast beforehand, it's not possible to get back that type information, though, to my knowledge.

Another option is using Array.getLength(arrayObject), which should work on all types of arrays, throwing an IllegalArgumentException, if the argument is not an array, which can be handled accordingly. This has the advantage of getting the array's size at once.

fozzybear
  • 91
  • 9