Getting instance of object? - java

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) …

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).

Checking if an object is an instance of a specific datatype given by a user

I am struggling with checking if an object is an instance of a specific datatype, which is given by user input. For example:
Object a = new Object();
String userDataType = JOptionPane.showInputDialog("What kind of datatype do you want to check?");
if(Object a instanceof userDataType)) doStuff();
I tried reflections but I still don't manage to get behind this...
Thank you in advance!
Try comparing with the getSimpleName() of the class of the object, which returns just the unqualified class name (without the package name).
Object o;
String userInput;
if (o.getClass().getSimpleName().equalsIgnoreCase(userInput))
The instanceof keyword works by comparing it to an actual object type, not a string. For example:
Object a = getUseObject();
if( a instanceof String ) doStuff(); // if a is actually a String
else if (a instanceof double[]) doStuff(); // if a is actually an array of doubles
Cast it to the datatypes you wish to check for, handle exceptions as required.

Dynamically create an object in java from a class name and set class fields by using a List with data

I have a List that contains data with String type -> ["classField1", "classField2", "classField3"]
I have a method (myMethod(List list, String className)) that accept as parameter the List. So, I can pass this List through the parameter to myMethod(List list, String className).
In myMethod, I want to create one object, that will be instance of the className, that is the second parameter. After that I want to set the fields of the class by using the data of the List.
Due to the fact that I want to obtain dynamically the fields of the class, the result of the above is that I have to cast each String value of the list, to the type of each field of the class.
I am sure that the order of the Strings inside to the List, are in the right order, and correspond to the fields of the class with the same order.
Does anybody have any idea how to perform the above?
Example:
["StringtempValue", "StringUnitOfMeasurement"] =>
Create instance object:
public class TempStruct {
private double tempValue;
private String unitOfMeasurement;
public TempStruct(double tempValue, String unitOfMeasurement) {
this.tempValue = tempValue;
this.unitOfMeasurement = unitOfMeasurement;
}
}
I try to give a solution with the following way:
Actually I want to create an object of an existing class and I tried to do that with reflection. I use the following code:
Class<?> cls = Class.forName(name);
Object clsInstance = (Object) cls.newInstance();
Field[] objectFields = clsInstance.getClass().getDeclaredFields();
But I get an exception to the 2nd line, when it tries to create the new object.
As #JB Nijet said I didn't know that the method getDeclaredFields() does not return the fields sorted.
Actually, I have a method that accept only List of Strings, so by using reflection I convert the object to List of string, and after that I want to do the opposite.
I didn't think any other way to do it.
Dynamic instantiation of objects can get pretty complex, and your scenario touches upon several aspects:
converting the object values from String to the appropriate type
loading the right class from the class name and creating an instance
assigning those values into the object
A thorough discussion of each of those points would take up an entire chapter in a no-doubt riveting treatment of Java as a dynamic language. But, assuming you don't have the time to learn these intricacies, or take a dependency on some huge third party library, let's whip up something that gets you on your way. Please keep your hands inside the vehicle at all times as the ride is going to get bumpy.
Let's tackle the issue of type conversion first. The values are provided as Strings, but your object will store them as double, long, int, etc. So we need a function that parses a String into the appropriate target type:
static Object convert(Class<?> target, String s) {
if (target == Object.class || target == String.class || s == null) {
return s;
}
if (target == Character.class || target == char.class) {
return s.charAt(0);
}
if (target == Byte.class || target == byte.class) {
return Byte.parseByte(s);
}
if (target == Short.class || target == short.class) {
return Short.parseShort(s);
}
if (target == Integer.class || target == int.class) {
return Integer.parseInt(s);
}
if (target == Long.class || target == long.class) {
return Long.parseLong(s);
}
if (target == Float.class || target == float.class) {
return Float.parseFloat(s);
}
if (target == Double.class || target == double.class) {
return Double.parseDouble(s);
}
if (target == Boolean.class || target == boolean.class) {
return Boolean.parseBoolean(s);
}
throw new IllegalArgumentException("Don't know how to convert to " + target);
}
Ugh. This is ugly and handles only intrinsic types. But we're not looking for perfection here, right? So please enhance as appropriate. Note the conversion from String to some other type is effectively a form of deserialization, and so you're placing constraints on your clients (whoever is giving you the Strings) to provide their values in specific formats. In this case, the formats are defined by the behavior of the parse methods. Exercise 1: At some point in the future, change the format in a backwards incompatible way to incur someone's wrath.
Now let's do the actual instantiation:
static Object instantiate(List<String> args, String className) throws Exception {
// Load the class.
Class<?> clazz = Class.forName(className);
// Search for an "appropriate" constructor.
for (Constructor<?> ctor : clazz.getConstructors()) {
Class<?>[] paramTypes = ctor.getParameterTypes();
// If the arity matches, let's use it.
if (args.size() == paramTypes.length) {
// Convert the String arguments into the parameters' types.
Object[] convertedArgs = new Object[args.size()];
for (int i = 0; i < convertedArgs.length; i++) {
convertedArgs[i] = convert(paramTypes[i], args.get(i));
}
// Instantiate the object with the converted arguments.
return ctor.newInstance(convertedArgs);
}
}
throw new IllegalArgumentException("Don't know how to instantiate " + className);
}
We're taking a lot of shortcuts here, but hey this isn't the sistine chapel we're creating. Simply load the class and search for a constructor whose number of parameters matches the number of arguments (i.e., arity). Overloaded constructors of the same arity? Nope, not gonna work. Varargs? Nope, not gonna work. Non-public constructors? Nope, not gonna work. And if you can't guarantee your class will provide a constructor that sets all the fields like your example TempStruct does, then I'll call it a day and grab a beer, because this approach is DOA.
Once we find the constructor, loop over the String args to convert them to the types expected by the constructor. Assuming that works, we then invoke the constructor via reflection, wave the magic wand and say abracadabra. Voilà: you have a new object.
Let's try it with an extremely contrived example:
public static void main(String[] args) throws Exception {
TempStruct ts =
(TempStruct)instantiate(
Arrays.asList("373.15", "Kelvin"),
TempStruct.class.getName());
System.out.println(
ts.getClass().getSimpleName() + " " +
ts.tempValue + " " +
ts.unitOfMeasurement);
}
Output:
TempStruct 373.15 Kelvin
GLORIOUS
I used to have the same kind of problem and a hashMap turned out to be the solution for me.
Check it out:
http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html
Take a look at the http://commons.apache.org/beanutils/ package. It allows to access fields by name.

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);
}

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

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());
}

Categories