Is it better to use class.isEnum() or instanceof Enum? - java

I have an object. I want to check to see if it is of type enum. There are two ways to do this.
object.getClass().isEnum()
or
object instanceof Enum
Is one better?

In my opinion object instanceof Enum is better for several reasons:
It is very obvious what is asked here: "is this an enum"?
It doesn't risk a NullPointerException (if object is null, it will just evaluate to false)
It's shorter.
The only reason I'd see for using isEnum() would be if I only have access to the Class object and not to a concrete instance.

You need to use the latter (object instanceof Enum) because the former may not work with enum constants with constant-specific class bodies.
For example, for this enum type:
enum MyEnum {
FOO { }
}
The expression MyEnum.FOO.getClass().isEnum() returns false.
If you want to check if an object is a enum constant without instanceof Enum, you have to use this (much more complicated) expression:
static boolean isEnum(Object obj) {
Class<?> cls = obj.getClass();
Class<?> superCls = cls.getSuperclass();
// Be careful, Object.class.getSuperclass() returns null
return cls.isEnum() || (superCls != null && superCls.isEnum());
}

Related

Comparison of Java objects [duplicate]

This question already has answers here:
Parentheses around data type?
(5 answers)
Closed 7 years ago.
I'm new to Java, and am reading a Java book; at one point it talks about when you may want to override the built in function, equals(). For instance, if an object has a variable ID, and two objects have the same ID, you may want them to be considered to be equal. It gave example code which looks more or less like:
public boolean equals(Object obj) {
if((obj != null) && (obj instanceof myClass)) {
myClass object1 = (myClass)obj;
if(this.ID == object1.ID) {
return true;
}
}
return false;
}
I don't fully understand what's going on in the third line. I'm unsure about why it's necessary and you can't just compare obj.ID and this.ID in the if() statement. My guess is that it's because obj is just declared as a generic object which may not have an ID, so you need to create a new object, object1 which is of the correct class to look at the ID.
Am I correct here? What exactly is going on in that line?
In your code Object obj is a reference to an Object. The code at this point makes no assumptions about which type of Object it is.
When you do
myClass object1 = (myClass) obj;
you are casting the type of the reference to an object which this will either succeed because it is an instance of that type or fail throwing ClassCastException.
This creates a new reference but the underlying object is unchanged by this, nor is it copied.
Note: the obj != null check is redundant as null is not an instanceof of any class, nor does it trigger an exception. i.e.
Object o = null;
boolean b = o instanceof Object; // always false, never throws an exception.
A shorter version of this method could read.
public boolean equals(Object obj) {
if(obj instanceof myClass) {
myClass object1 = (myClass)obj;
return ID == object1.ID;
}
return false;
}
or even
public boolean equals(Object obj) {
return obj instanceof myClass && ID == ((myClass) obj).ID;
}
In Java 8 you could write
public boolean equals(Object obj) {
return Optional.ofNullable(obj)
.filter(o - > o instanceof myClass)
.map(o -> (myClass) o)
.filter(m -> ID == m.ID)
.isPresent();
}
On the 3rd line, no object is being created.
The first thing you need to understand about java is that there are primitives like int, char, double and objects, which are everything else, and objects are always accessed by reference.
So, Object obj is a reference to objects of type Object, and at runtime it will be referring to some object.
Then, further down, when you say myClass object1 you are not creating any object; you are just declaring a variable called object1 which will be referring to objects of type myClass. But there is no object yet.
So, when you say myClass object1 = (myClass)obj; you are assigning the reference obj to the reference object1. And since it would normally be invalid to make an assignment between different types, you are using a type cast (the (myClass) part) to tell the compiler that you know what you are doing, and you are sure that obj will be pointing to an object of type myClass at that point. So, the compiler allows you to make the assignment.
After the assignment, both obj and object1 are pointing to the same object, but the usefulness of object1 now is that you can view this object as an object of type myClass, so you can access its members.
Your guess is almost correct: obj is declared to have type Object and Object can be anything, a String for example, it does not have to have the member named ID, so, you can't just look at it to compare. So, the code you quoted first check if the obj is of the same type (if it isn't, then you know it does not equal), and then (on the line you are asking about) casts it to that type.
I said, your guess was almost correct, because you suggested that a new object of type myClass is created. This is not true. The assignment myClass object1 = (myClass)obj; does not create any new objects, it merely makes a new variable object1 refer to to the same object referred by obj, and tells the compiler that it should now know that that object is actually of type myClass.
Yes. The third line is inside an if statement that says obj instanceof myClass. At that point you know that it is of type myClass. Assuming myClass has an ID like in your code then you know that both objects have ID properties and you can use those for comparison.
Research the term "Object Casting".
the obj instanceof myClass is making sure that obj is the same type as this. Now we know it is safe to cast and Object obj into a myClass object1
The test for null is not needed, because instanceof is false for nulls.
Just use:
if (obj instanceof myClass) {
Otherwise, your code is fine, assuming ID is a primitive (especially, not a String).

Getting instance of object?

I have a slight problem. I wrote a function that should generate table for a list of objects (it could be Date or custom one or whichever). Parametars of this function are "List list" and "List headings". So, here is the question, why is this line
if (value.getClass().isInstance(Date.class) ...
not executing, even thou when I print value.getClass() is says the: class java.util.Date. Also a question, how to check if "value" is List? Thanks a lot in advance :)
Here is the part of the code:
for (Object o : list) {
List<String> atributes = new ArrayList<String>();
for (java.lang.reflect.Field field :o.getClass().getDeclaredFields()) {
field.setAccessible(true);
Object value = field.get(o);
if (value != null) {
if (value.getClass().isInstance(Date.class)) {
atributes.add(convertDateToString((java.util.Date) value));
}
atributes.add(value.toString());
}
} ...
You're misusing Class#isInstance, which returns true if Date.class is an instance of value.getClass():
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.
Rather, you want either:
if(value instanceof Date)
or
if(Date.class.isInstance(value))
The correct way to check if an object is an instance of some Class is to use "instanceof" statement.
So, you should be doing this:
if (value instanceof Date) {
atributes.add(convertDateToString((java.util.Date) value));
}
Hope this will help you.
value.getClass().isInstance(Date.class) asks if Date.class which is of type Class is an instance of a class that is assign-compatible with the class of value. That is false unless value is an instance of Class or Object.
Use operator instanceof instead:
if (value instanceof Date) …

How I check if a variable is a "class" reference

How do I check if a given variable is a Class (generic type)? I really don't know how to ask the question better, but let's consider this code:
Object[] o = new Object[] { "string", 12, MyClass.class, new MyClass() };
for (int i = 0; i < o.length; i++) {
if (o[i] instanceof String) ... // TRUE for [0]
else if (o[i] instanceof Integer) ... // TRUE for [1]
else if (o[i] instanceof ???) ... // TRUE for [2] ???
else if (o[i] instanceof MyClass) ... // TRUE for [3]
else ...
}
How do I check the type of the third element of the o array?
Use instanceof to test if it's a class (of any type):
if (o[i] instanceof Class)
Use == to test if it's a specific class:
if (o[i] == MyClass.class)
Class literals are effectively static constants, so there's only one of each class literal per JVM.
Note: If there are multiple class loaders in play then the test for == may be false even though it "should" be true if the two instances were loaded using different class loaders. In this case, even o[i].equals(MyClass.class) will be false.
Use like bellow with instanceOf operator
o[i] instanceof Class
MyClass.class is a literal of type Class, so instance of Class should do.
else if (o[i] instanceof Class) ...
Exactly the same way you'd check if it was an Integer or String. If you want to use the generic type parameter, it'll have to be the ? wildcard:
else if (o[i] instanceof Class<?>) ...
Since generic information is erased at runtime, and it doesn't seem you want to test that it's a specific class anyway.

How do I check if a given object is an instance of certain class when in Object[] array?

I was trying to find out how to determine which class a given object instantiate when it's in Object[] array. For example:
Object[] array = new Object[]{175, "sss", new Table(), true};
Object obj = array[0]; // hmm... can this be used as an integer or maybe as a string?
Is it even possible?
You can call getClass() to find out the class of a particular object, or you can use instanceof to check a specific type:
if (array[0] instanceof Integer) {
}
Normally having to do a lot of this indicates a weakness in your design though - you should try to avoid needing to do this.
You can try using instanceof or you can try getClass().isAssignableFrom(), whatever fits your needs
You can test whether it is an instance of a pre-known class (and cast it) like this:
if (obj instanceof String) {
String s = (String) obj; //casts the obj now you know it's a String
}
I like to think of this not as making any changes to the object but just as revealing its true character. For example, it's a bit like seeing a person and not knowing what language they speak - the person is still French, or Italian, just that you don't know which yet. The cast (i.e. (String) obj) is you telling the compiler the equivalent of "I know this person speaks French"
Or you can gets its class like this:
Class<?> clazz = obj.getClass();
A Class instance can be used to make the same check:
String.class.isInstance(obj) {
String s = String.class.cast(obj);
}

Check if an object belongs to a class in Java [duplicate]

This question already has answers here:
How to determine an object's class?
(13 answers)
Closed 9 years ago.
Is there an easy way to verify that an object belongs to a given class? For example, I could do
if(a.getClass() = (new MyClass()).getClass())
{
//do something
}
but this requires instantiating a new object on the fly each time, only to discard it. Is there a better way to check that "a" belongs to the class "MyClass"?
The instanceof keyword, as described by the other answers, is usually what you would want.
Keep in mind that instanceof will return true for superclasses as well.
If you want to see if an object is a direct instance of a class, you could compare the class. You can get the class object of an instance via getClass(). And you can statically access a specific class via ClassName.class.
So for example:
if (a.getClass() == X.class) {
// do something
}
In the above example, the condition is true if a is an instance of X, but not if a is an instance of a subclass of X.
In comparison:
if (a instanceof X) {
// do something
}
In the instanceof example, the condition is true if a is an instance of X, or if a is an instance of a subclass of X.
Most of the time, instanceof is right.
If you ever need to do this dynamically, you can use the following:
boolean isInstance(Object object, Class<?> type) {
return type.isInstance(object);
}
You can get an instance of java.lang.Class by calling the instance method Object::getClass on any object (returns the Class which that object is an instance of), or you can use class literals (for example, String.class, List.class, int[].class). There are other ways as well, through the reflection API (which Class itself is the entry point for).
Use the instanceof operator:
if(a instanceof MyClass)
{
//do something
}
I agree with the use of instanceof already mentioned.
An additional benefit of using instanceof is that when used with a null reference instanceof of will return false, while a.getClass() would throw a NullPointerException.
Try operator instanceof.
The usual way would be:
if (a instanceof A)
However, there are cases when you can't do this, such as when A in a generic argument.
Due to Java's type erasure, the following won't compile:
<A> boolean someMethod(Object a) {
if (a instanceof A)
...
}
and the following won't work (and will produce an unchecked cast warning):
<A> void someMethod(Object a) {
try {
A casted = (A)a;
} catch (ClassCastException e) {
...
}
}
You can't cast to A at runtime, because at runtime, A is essentially Object.
The solutions to such cases is to use a Class instead of the generic argument:
void someMethod(Object a, Class<A> aClass) {
if (aClass.isInstance(a)) {
A casted = aClass.cast(a);
...
}
}
You can then call the method as:
someMethod(myInstance, MyClass.class);
someMethod(myInstance, OtherClass.class);

Categories