Im new to Java, is there a method in Java that tells you the type of an Object?
For example in Python if you type
type(34) it would return int
type('abc') would return string
I've been looking everywhere but I can't find a way of doing it. Any help?
Thanks a lot.
The instanceof operator is the handiest way to do runtime type checking:
if (someObject instanceof String) {
// It's a string
}
Alternately, on any instance, you can use getClass, which gives you the Class instance for the type of the object.
Class c = someObject.getClass();
The Class instance will have a getName method you can call to get a string version of the name (and lots of other handy methods).
You can get a Class object from a type name using .class, e.g.:
Class stringClass = String.class;
As Peter Lawrey points out in the comments, all of these assume you're dealing with an object reference, not a primitive. There's no way to do a runtime type check on a primitive, but that's okay, because unlike with object references (where your compile-time declaration may be Object), you always know what your primitive types are because of the declaration. It's only object types where this really comes up.
If you find yourself doing a lot of explicit type checks in your Java code, that can indicate structure/design issues. For the most part, you shouldn't need to check type at runtime. (There are, of course, exceptions.)
Basically we can achieve our goal by using the method overriding
class GetType {
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");
}
}
public static void main(String args[]) {
double doubleVar = 1.5;
int intVar = 7;
float floatVar = 1f;
GetType objType = new GetType();
objType.printType(doubleVar);
objType.printType(intVar);
objType.printType(floatVar);
}
Related
I have to follow the below UML diagram to design a programme.
The programme is supposed to generate 2 random integers, and ask user for input the answer to the sum of said integers.
However, I am not sure how to make use of the method static void getTwoIntegers(MyInteger m, MyInteger n) , or what to put inside it.
I have tried initialising 2 MyInteger objects with MyInteger int_1 = new MyInteger(m); and (n) in this method, but get a "cannot be resolved" error everytime I call its getter method int_1.getInteger();
And since the method getTwoIntegers is void, I cannot just return 2 random integers. I'm truly stuck on how to utilise this method
Any ideas? Thanks so much
Simple demo of what your implementation can accomplish.
The MyInteger objects passed as parameters (m and n) can be modified by the implementation of getTwoIntegers using the setInteger method of the class.
public class Main
{
public static void main(String[] args) {
MyInteger a = new MyInteger(333);
MyInteger b = new MyInteger(444);
System.out.println("before: " + a.getInteger() + "," + b.getInteger());
getTwoIntegers(a,b);
System.out.println("after: " + a.getInteger() + "," + b.getInteger());
}
public static class MyInteger {
private int val;
public MyInteger() { val = 0; }
public MyInteger(int v) { val = v; }
public void setInteger(int n) { this.val = n; }
public int getInteger() { return val; }
}
static void getTwoIntegers(MyInteger m, MyInteger n) {
// in your case modify implementation to produce random numbers
m.setInteger(222);
n.setInteger(555);
}
}
Prints:
before: 333,444
after: 222,555
Gardener's answer nailed it. For the records, I'd like to share some more thoughts.
This class diagram is misleading. The parameters of an UML operation have a direction that should be indicated in front of the parameter name. It can be in, out, inout. If the direction is omitted in the diagram, UML assumes that it's an in argument. Which assumes that the parameter is not muted by the operation.
If it would have been correctly specified as getTwoIntegers(out m: MyInteger, out n: MyInteger) (yes, UML syntax order is slightly different from Java), you would have understood that the values of m and n are provided for the output of the values of the operation, and not as input. And indeed, as Gardener explained, in Java you can provide a class object that can then be mutated to store the results; because class objects are passed by reference (i.e. it's the same object that is used and not a copy). This is by the way why a class MyInteger is used in this lab instead of a built-in type int.
Other unrelated UML remarks: there is no static type modifier keyword in UML. Either is it marked as {static} or is it underlined. Last but not least, there should be no multiplicity on a dashed dependency arrow. Multiplicities are for associations, i.e. structural relationships.
I'm trying to make a method that accepts a number of any primitive type (either byte, int, float, long, double or short). Then after a certain checking method either returns that very same number (i.e., for example, it accepts double and returns double) or it returns a zero.
So far I've come to this:
<AnyNumType> AnyNumType cancelAdd(AnyNumType val, String point) {
if (checkModuleMatchAndOff(point) == true) return 0;
else return val;
}
But I get a type mismatch error (with 0 underlined and explained: "Cannot convert from int to AnyNumType"). Is there a way to cope with this zero problem? I intend to use this method in equations so I really need it to return primitive types.
EDIT: Thank you very much for all your replies, guys!
No, you're not accepting any primitive type; you're accepting any object type. You may think you're accepting primitive types, but Java generics can use only reference types. Your values are being boxed when passed into this method. You could pass a String in as val.
That should indicate why 0 can't be converted to AnyNumType -- AnyNumType can be any reference type.
The best way to accept any primitive type is to have overloads for every primitive type, like many methods in the core library do. You can return the equivalent of 0 in each overload, e.g.
byte cancelAdd(byte val, String point)
{
if (checkModuleMatchAndOff(point) == true) return (byte) 0;
else return val;
}
The overloads for the other primitive types will look very similar.
You could change your method type to:
<AnyNumType extends Number> AnyNumType cancelAdd(AnyNumType val, String point);
I don't know exactly what you want do do inside the method, but this should allow you to pass in primitives via auto-boxing.
But it is not generally possible to use generics for primitive types in Java, autoboxing is, I think, the only way.
Returning a value other than the object you got in is possible, but you'd need some ugly reflection and casts, unfortunately. And it would not support all possible types.
(Maybe there is some library for this somewhere?)
For any doubters out there, here's sample code fresh out of Eclipse, without compilation errors, that demonstrates this:
public class NumberGenerix {
#SuppressWarnings("unchecked")
public static <Any extends Number> Any f(Any x) {
Class<?> k = x.getClass();
if (k == Integer.class) {
return (Any) Integer.valueOf(0);
} else if (k == Double.class) {
return (Any) Double.valueOf(0.0);
} else if (k == Long.class) {
return (Any) Long.valueOf(0L);
} else {
// and so on.
throw new RuntimeException("unsupported number type: " + k);
}
}
public static void main(String...args) {
Integer a = f(42);
System.out.println("a == " + a);
Long b = f(42L);
System.out.println("b == " + b);
Double c = f(42.0);
System.out.println("c == " + c);
}
}
I'm trying to make a function that will invoke the constructor of a class given a set of arguments
package testytest;
import java.lang.reflect.Constructor;
public class MainClass {
public static <T> T newClass(Class<?> inst, Object ... args){
#SuppressWarnings("unchecked")
Constructor<?> [] ctor = (inst.getDeclaredConstructors());
int argIndex = 0;
ctorLoop: for(Constructor<?> x : ctor){
argIndex = 0;
for(Class<?> s : x.getParameterTypes()){
if(argIndex > args.length || args[argIndex++].getClass() != s){
if(argIndex <= args.length)
System.out.println("Param doesnt match : " + args[argIndex-1].getClass() + " with " + s);
continue ctorLoop;
}
}
try{
return (T)x.newInstance(args);
}catch(Exception e){
System.err.println("Error in instantiating instance of class : " + inst);
return null;
}
}
System.err.println("No instance of constructor found for class " + inst);
return null;
}
public static void main(String[] args) {
System.out.println(newClass(Double.class,5.0));
}
}
which gives me the error
Param doesnt match : class java.lang.Double with double
Param doesnt match : class java.lang.Double with class java.lang.String
No instance of constructor found for class class java.lang.Double
looking at the line
Param doesnt match : class java.lang.Double with double
is there a way to natively make this boolean match without case swapping every native type (double,float,long,int,etc?)
There are constants defined in the wrapper classes that represent the Class objects for the primitive types. For double, use Double.TYPE.
The Class instance representing the primitive type double.
That should match the presumed double argument for the constructor you're looking for.
Other examples for other primitives are Integer.TYPE, Float.TYPE, Short.TYPE, Byte.TYPE, Long.TYPE, Character.TYPE, and Boolean.TYPE. There is even Void.TYPE for void.
No, there isn't. Both the reference type java.lang.Double and the primitive type double have corresponding Class objects. There is no way to go from one Class object to another (boxing/unboxing).
You'll have to keep your own (bi)map.
The easy way to do this is with java.beans.Statement. It handles all this conversion for you automatically.
Say, there is a following example:
class Super {
public int i = 3;
public void m(Object o) {
System.out.println("Object " + i);
}
public void m(String o) {
System.out.println("String " + i);
}
}
public class Sub extends Super {
public Sub() {
i = 5;
}
public static void main(String[] args) {
Super s = new Sub();
Object o = "";
s.m(o);
s.m("");
}
}
The result of this code is:
Object 5
String 5
But I thought it would be:
String 5
String 5
Don't quotes set String as this object's type? There are definitely some cases of casting to String with a help of quotes, so I'm a little confused about this basic example. Thanks in advance.
The type of the method is determined in compile time, and not in run time. The dynamic dispatch exists only for the "parameter" this - there is no dynamic dispatch for parameters in static typing languages such as java.
The compiler "choses" which method should be invoked, and since o is of type Object - it choses m(Object) - it has no way to know that the dynamic type of o is actually a String.
If you are interested - a common way to overcome this issue in some cases is using the visitor design pattern.
In your specific case, in order to "force" the activation of m(String) you should use m(o.toString())
In sb.m(o), you're calling m() with an Object reference, so Java chooses that overload. Java will not choose a more specific overload than the reference type you pass it. It will go up the inheritance chain though. Say you didn't have m(String o), calling sb.m("Hello") would still be legal, but it would call the object version.
If you were to do sb.m((String) o), you would get your expected behavior.
You declared the object as Object so its type is Object. Types in Java are strong and static so when you declare an object as type Type that is what its type will be for life.
If you want it to be a string you'll have to use a toString method or a cast (String)o
You are downcasting the String to an Object. What you are doing is similar to this.
public class Sub extends Super {
public Sub() {
i = 5;
}
public static void main(String[] args) {
Super s = new Sub();
Object o = "";
System.out.println("Object Type = " + o.getClass().getName());
s.m(o);
s.m((Object)"");
}
}
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?
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.
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 );
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/
Just use:
.getClass().getSimpleName();
Example:
StringBuilder randSB = new StringBuilder("just a String");
System.out.println(randSB.getClass().getSimpleName());
Output:
StringBuilder
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){...}
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.
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.
I did it using: if(x.getClass() == MyClass.class){...}
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());
}
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
}
}
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
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
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
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
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");
}
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