Java - looping and through variables of instance of a class - java

I have a class
Class Test{
private String something ;
private String somethingElse;
private String somethingMore;
}
I am creating an instance of this.
myInst = new Test();
and adding values to first and second variables.
Now I need to check if any of the variable is null.
I know I can do this like if(myInst.something == null)
but for each item I add to the class it's difficult to do.
Is there anyway that i can check the instance by looping through all elements and seeing anything is null.
just like -
for(i=0; i< myInstanceVariables ; i++)
{
if(myInstanceVariable == null ){
//do something
donotDisplay(myInstanceVariable)
}
TIA

You can use Reflection using Fields from your instance. In your class, add this code. It will take all the fields and get their value.
Field[] fields = getClass().getDeclaredFields(); // get all the fields from your class.
for (Field f : fields) { // iterate over each field...
try {
if (f.get(this) == null) { // evaluate field value.
// Field is null
}
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
}
}
Here is a sample code: https://ideone.com/58jSia

You have to use reflection over Field of the Class.
myInst = new Test();
for (Field field : myInst.getClass().getDeclaredFields())
if (field.get(myInst) == null)
// do something

You can use reflection, however, in your case you only have String values, and thus it would also make sense to use a HashMap (for instance):
HashMap hm = new HashMap();
hm.put("something", "itsValue");
hm.put("somethingElse", null);
Now you can put as many values as you would like, and iterate through them like this:
Set set = hm.entrySet();
Iterator i = set.iterator();
while(i.hasNext()){
Map.Entry me = (Map.Entry)i.next();
System.out.println(me.getKey() + " : " + me.getValue() );
}

Related

java.lang.InstantiationError when creating instance of static inner class with Objenesis

I am trying to create a utility method that should be able to deep-clone any object.
(Object.clone() only works on Object implementing Cloneable and I heard it's flawed anyways.)
I am using Objenesis to create new instances of objects without the use of constructors.
However, when trying to clone a JFrame I get the following Exception:
(using this class because I think it should be a good and complex test)
java.lang.InstantiationError: [Ljava.util.concurrent.ConcurrentHashMap$Node;
at sun.reflect.GeneratedSerializationConstructorAccessor12.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:48)
at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73)
I am open to any solution, not necessarily limited to Objenesis.
My Code:
private static ObjenesisStd OBJENESIS = new ObjenesisStd();
#SuppressWarnings("unchecked")
public static <T> T clone(T object, boolean deep){
if(object == null){
return null;
}else{
try {
T clone = (T) OBJENESIS.newInstance(object.getClass());
List<Field> fields = ReflectionUtil.getAllFieldsInHierarchy(object.getClass());
for(Field field : fields){
boolean isAccessible = field.isAccessible();
boolean isFinal = ReflectionUtil.isFinal(field);
field.setAccessible(true);
ReflectionUtil.setFinal(field, false);
Class<?> type = field.getType();
if(!deep || type.isPrimitive() || type == String.class){
field.set(clone, field.get(object));
}else{
field.set(clone, clone(field.get(object), true));
}
field.setAccessible(isAccessible);
ReflectionUtil.setFinal(field, isFinal);
}
return clone;
} catch (Throwable e) {
e.printStackTrace();
//throw new RuntimeException("Failed to clone object of type " + object.getClass(), e);
return null;
}
}
}
public static void main(String[] args) {
GetterSetterAccess access = new GetterSetterAccess(JFrame.class);
JFrame frame = new JFrame("Test Frame");
for(String attr : access.getAttributes()){
System.out.println(attr + " " + access.getValue(frame, attr));
}
System.out.println("----------------------------------------------");
frame = clone(frame, true);
for(String attr : access.getAttributes()){
System.out.println(attr + " " + access.getValue(frame, attr));
}
}
EDIT: Got it to work with the accepted answer and a few more fixes:
Avoided cloning Wrappers of Primitive Types (Integer.class etc.)
Avoided cloning Classes (Objects of the class Class.class)
Stored the cloned objects in a Map and reused them, so if Object A has a reference to Object B and Object B one to Object A it doesn't get stuck in an infinite loop. I also used a Map that checks for exact equality (==) instead of using equals().
Created a custom exception class which would just be passed on instead of throwing a new exception on every level (causing a huge caused-by-depth).
I finally figured it out. Your code doesn't handle arrays. So it fails with instantiating "[Ljava.util.concurrent.ConcurrentHashMap$Node;" which is an array of Nodes.
However, I will advocate that indeed, you should not do that. You will end up with fairly complicated code. Depending on what you want to do, you could use Jackson or XStream to do a marshall / unmarshall to perform the copy.
If you really want to continue that path, you will need something like this after the null check of your clone method.
if(object.getClass().isArray()) {
int length = Array.getLength(object);
Object array = Array.newInstance(object.getClass().getComponentType(), length);
for (int i = 0; i < length; i++) {
Array.set(array, i, clone(Array.get(object, i), true));
}
return (T) array;
}

Getting values from object in java

How I can get those values from this object? I was trying to getFields, getDeclaredFields etc. but everything is empty.
The problem is that Field[] myField = o.getClass().getDeclaredFields(); always return an empty array.
I am getting those values from database this way:
Query reqDisplayResponse = em.createNativeQuery("Select * FROM pxds_displayResponse");
List<Object> displayResponseList = reqDisplayResponse.getResultList();
And I want to print those values:
for(Object o: displayResponseList) {
for(Field field: o.getClass().getDeclaredFields()) {
log.info(field.getName());
}
}
Unfortunately log.info is unreachable.
Ok, here is solution. In fact object is an array, getDeclaredFields() return empty table, in documentation we can read:
If this Class object represents an array type, a primitive type, or void, then this method returns an array of length 0.
So in this situation it is useless. All we have to do is iterate over this object this way:
for(Object o: displayResponseList) {
for(int i = 0; i < 7; i++) {
System.out.println(((Object[])o)[i].toString());
}
System.out.println("...............");
}
Hope this will help someone in future.
You should use getDeclaredField, and then use get on it, passing the object as parameter.
Like this:
Field myField = object.getClass().getDeclaredField("_myField");
myField.setAccessible(true);
return (Integer) myField.get(object);
Try to display the object 'o' like an array:
for(int index = 0 ; index < 10 ; index++){
Log.info(String.valueOf(o[index]));
}
I think those fields you are trying to access are private
So in order to access private fields you have to:-
for (Field f : object.getClass().getDeclaredFields()) {
f.setAccessible(true);
Object o;
try {
o = f.get(object);
} catch (Exception e) {
o = e;
}
System.out.println(f.getGenericType() + " " + f.getName() + " = " + o);
}
This is an ID given by the Eclipse debugger, not by Java. You cannot access it.
There is System.identityHashCode(Object) to get the Object identity. (not the same ID)
If you want an ID like the one shown in the Eclipse debugger, you'd have to allocate them yourself.
Here is some general direction how you could do something like that:
Elegant way to assign object id in Java
Gwozdz, I think I understand your question. If I understood correctly, you are having problemas to access the value from a list of objects, in your image code example I'm seeing that you are using List. Try to use List<Object[]> and then use a foreach to access every value of your matrix.
List<Object[]> displayResponseList = reqDisplayReponse.getResultList();
foreach(.....){
foreach(.....){
[manipulate you object value here]
}
}
Just for your information: Matrix is a list of lists. In that case a list of array.

Method.Invoke without knowing the paramaters

I am using Method.Invoke in java to dynamically call methods in another class. The only issue is that if the methods have paramaters i need to start that in the class.getDeclaredMethod("method", something.class) or else it wont see those methods. The issue with this that i don't know when calling the methods what the parameters will be. How do I get around this?
Also I have done this in C# and its easy and does not require me to state the parameters but this is in Java.
Here is the code that does the Invoke:
public void DoCommand(String msg){
System.out.println(msg);
String[] temp = msg.split(" ");
String command = temp[0];
Class c = commander.getClass();
try {
Object obj = c.newInstance();
try {
System.out.println("'" + command + "'");
Method method = c.getDeclaredMethod(command);
Object[] pars = new Object[temp.length];
for(int i = 0; i < pars.length; i++){
pars[i] = temp[i + 1];
}
if((String)pars[pars.length - 1] == null){
pars[pars.length - 1] = socket;
}
Parameter[] paramaters = method.getParameters();
Object[] endParameters = AltimitConverter.ConvertParameters(pars, paramaters);
try {
method.invoke(obj, endParameters);
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {}
}catch (NoSuchMethodException e){
System.out.println(e.toString());
}
}catch (Exception e){
System.out.println(e.toString());
}
}
So how do I call different methods with different parameters without stating the parameters when getting the method.
This is the C# version that does work:
private static void DoCommand(string msg, Socket soc){
string[] temp = msg.Split (' ');
string command = temp [0];
Type type = commandObject.GetType ();
MethodBase commandFunction = type.GetMethod (command);
if (commandFunction != null) {
object[] pars = new object[temp.Length - 1];
for (int i = 0; i < pars.Length; i++) {
pars [i] = temp [i + 1];
}
if ((string)pars [pars.Length - 1] == "") {
pars [pars.Length - 1] = soc;
}
ParameterInfo[] paramaters = commandFunction.GetParameters ();
object[] endParamaters = AltimitConverter.ConvertParams (pars, paramaters);
if (commandFunction != null) {
try {
commandFunction.Invoke (commandObject, endParamaters);
} catch (Exception e) {
Debug.Log (e);
}
} else {
Debug.Log ("commandFunction is null");
}
}
}
Instances of java.lang.reflect.Method reflect specific methods. Each one is associated with a specific class, has a specific parameter list, and has a specific return type. When method overloading is in play, each of the overloaded methods will be reflected by a distinct Method object; these are not interchangeable.
If you need to account for selecting among overloaded methods, then you can do so only with reference to the number and types of the intended arguments. If you have to rely on the arguments themselves to determine matching parameter types, then you're looking at duplicating Java's method-resolution logic, which is complex.
In the event that you need only worry about looking up a non-overloaded method declared by the subject class itself (i.e. not inherited) then you can invoke getDeclaredMethods() on the Class object and scan the resulting array of Method objects for one with the correct name.
You can go a little way into overloaded methods while preserving your sanity if different overloads are distinguished by different numbers of parameters, or maybe if there are specific limits on the parameter type patterns you need to account for, but at that point you really should be asking yourself whether there's a better way. This kind of design absolutely begs for trouble.
I figured out a solution. I created a function to take the intended parameters which are strings and convert them to a data type depending on if it looks like a float, Integer, or string. then i send that into another method that gets all methods in a class and get the ones with the method name i am trying to call and then gets the one with the data types i had in the object[] returned from the first method. and then i use the method i got and the converted data types to call the method.

Can we get the exact location where the condition fails, in an If case having multiple conditions?

I am new to Java,
Here is my code,
if( a.name == b.name
&& a.displayname == b.displayname
&& a.linkname == b.linkname
......... )
return true;
else
return false;
I will call this method and have to check that all properties of objects 'a' and 'b'.
Each object will have more than 20 properties. So, it is will be tidy if i use if case for each property.
An exception is throwed if the return is false and I have to report which property fails.
Is there any easy method to find where the condition fails within the if case.
Pls help. Ask if you are not clear about the question.
The question is, would you like to continue checking if one of the conditions fails?
You could do something like comparator where you have interface:
public interface IComparator {
boolean compare(YourObject o1, YourObject o2);
String getComparatorName();
}
Next you create set of implementations of that interface:
NameComparator implements IComparator {
private name="Name Comparator";
#Override
public boolean compare(YourObject o1, YourObjecto2) {
return o1.getName().equals(o2.getName());
}
#Override
public String getComparatorName() {
return name;
}
}
Next you store set of these comparators in arrayList and you iterate through them and record which one fails by adding them to some other collection.. Hope that helps!
For instance you create array:
IComparator[] comparators = new IComparator[]{ new NameComparator, new DisplayNameComparator};
List<IComparator> failedComparationOperations = new ArrayList<IComparator>();
for(IComparator currentComparator : comparators) {
if(!currentComparator.compare(o1, o2)) {
failedComparationOperations.add(currentComparator);
}
}
for(IComparator currentComparator: failedComparationOperations)
{
System.out.println("Failed Comparation at: "+currentComparator.getComparatorName());
}
You may use reflection: browse what fields are defined, and check each of them using method equals. Print error message if they're not equal, give summary at the end.
boolean equals = true;
Field[] fields = a.getClass().getDeclaredFields();
for (Field f: fields){
f.setAccessible(true);
try {
if (!f.get(a).equals(f.get(b))){
System.out.println(f.getName() + ": " + f.get(a) + "!="+ f.get(b));
equals = false;
};
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("equals?: " + equals);
If you need to know which of the conditions has failed you should check each of the conditions independently.
It might be a little overkill if you are dealing with this single requirement, but what about the Strategy Design Pattern?
http://sourcemaking.com/refactoring/replace-conditional-with-polymorphism
It should be an interesting option if you have other business rules that you can combine with this check.
If a and b are instances of the same class, let's assume A, and the fields are visible, then you can use reflections:
for (Field f : A.class.getFields()) {
try {
if (!f.get(a).equals(f.get(b))) {
throw new RuntimeException("Field " + f.getName() + " is different.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
Without reflection you can't get maximum conciseness, but the followincg can help you to some extent. Make this kind of class:
class NamedEquals {
final String name;
final Object left, right;
NamedCondition(String name, Object left, Object right) { ...assign them... }
boolean areEqual() { return left.equals(right); }
}
Then make a List<NamedEquals>:
List<NamedEquals> conds = Arrays.asList(
new NamedEquals("name", left.name, right.name),
new NamedEquals("displayname", left. displayname, right.displayname),
...
);
And you can find if some of them fail:
for (NamedEquals eq : conds)
if (!eq.areEqual()) throw new ValidationException(eq.name);
Using a factory method can shorten the construction code:
static NamedEquals eq(String name, Object left, Object right) {
return new NamedEquals(name, left, right);
}
With that you can have
List<NamedEquals> conds = Arrays.asList(
eq("name", left.name, right.name),
eq("displayname", left. displayname, right.displayname),
...
);
How about?
// Adapted from your example:
if(!equalTo(a.name, b.name))
fail("name");
if(!equalTo(a.displayname, b.displayname))
fail("displayname");
... etc ...
...
// Allow for null values.
public boolean equalTo(Object a, Object b) {
return a != null ? a.equals(b) : b == null;
}
public void fail(String which) throws SomeException {
throw new SomeException("Failed on '"+which+"'!");
}
Another possible might be to turn each object into a Map<String,?>, perhaps by adding a Map<String,?> toMap() method to the value object, and implementing this by constructing a new map and dumping the value's fields into it. Then you can get the maps and do equals() on them.

Java Hashmap to Object while running

Is there any way to cast the value of a Java HashMap to an Object at runtime like this:
claas Foo {
public int a;
public String b;
}
Foo foo = new Foo();
HashMap<String, Object> map = new HashMap<String, Object>();
for(Map.Entry<Foo, Bar> entry : map.entrySet()) {
String propertyName foo = entry.getKey();
Object o = entry.getValue();
foo[propertyName] = o; // Does not wokring
}
I tryed to parse a SQL-Query result to a object. Now i've written my own Seralize-Algorithm. Bot it doesn't work. Is there a better way to Unerialize Object from the Database?
Connection connection = DriverManager.getConnection(instance);
PreparedStatement statment = connection.prepareStatement("SELECT * FROM Foo;");
Foo data;
ResultSet rs = statment.executeQuery(query);
if (rs != null && rs.next()) {
for (Field field : data.getClass().getDeclaredFields()) {
try {
if ((String.class.equals(field.getType()))) {
field.set(String.class, rs.getString(field.getName()));
} else if ((Boolean.class.equals(field.getType()))) {
field.set(Boolean.class, rs.getBoolean(field.getName()));
} else if ((Integer.class.equals(field.getType()))) {
field.set(Integer.class, rs.getInt(field.getName()));
}
} catch (IllegalAccessException e) {
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
}
It sounds like what you're actually trying to ask is:
Is there any way of accessing a variable dynamically by name at execution time?
To which the answer is "yes, but it's usually a bad idea".
You can use reflection:
Field field = Foo.class.getDeclaredField(entry.getKey());
field.set(foo, entry.getValue());
But it will be slow, and you'll only find out about invalid keys/values at execution time. It's generally a bad idea. If you only know things dynamically, you can keep them dynamic - keep them in the map. If you want to store arbitrary properties, there's usually a better way of approaching the problem (e.g. custom serialization) but without more details, we can't help you work out that better way.
(Also note that you'll need Map.Entry<String, Object>, not Map.Entry<Foo, Bar> for your entry variable.)

Categories

Resources