public static <A, B> B convert(A instance,
Class<B> targetClass) throws Exception {
B target = (B)targetClass.newInstance();
for (Field targetField : targetClass.getDeclaredFields()) {
targetField.setAccessible(true);
Field field =
instance.getClass().getDeclaredField(targetField.getName());
field.setAccessible(true);
targetField.set(target, field.get(instance));
}
return target;
}
Above is the code I get from forum, When I try to reflect an single type object it works, but when I try on the complex type which mean inside ClassA I got ClassB object, I got the java.lang.NoSuchFieldException. Can anyone help me?
You have two different classes, with, most likely, different set of fields.
So if your Class A doesn't have the same fields as your class B, then the exception is thrown.
I'd suggest using BeanUtils.copyProperties(source, target) from apache commons-beanutils. You just create the second object yourself, and pass it to the method. It will not throw an exception if fields differ.
What is your ultimate goal with this piece of code?
Two suggestion:
(1) You can drop the downcast at the first line of the method:
B target = targetClass.newInstance();
(2) Add a try catch so that you can see the name of the missing field. This will help you sort out the issue you're having:
Field field = null;
try {
field = instance.getClass().getDeclaredField(targetField.getName());
}
catch(NoSuchFieldException e) {
throw new RuntimeException("Didn't find field named '" + targetField.getName() + "'");
}
...
Another answer.
If I understand your comment correctly it seems that you have inner classes: Class B (Target) is a class that is defined inside class A. Something like this:
class A {
int n;
class B {
int n;
}
}
Although these two classes seem to have the same fields, and therefore - should not inude a field not found error - they are not.
Inner classes (unless they are defined as static) has a hidden field inserted by the compiler. This field is of the type of the outer class and points to the object that created the inner class object. When using reflection this field is exposed. As A does not have such field, an exception is raised.
Related
The below question is asked by 4th round interview by project director.
There is a class A . Any number of classes can be derived from A. Constraints is any subclass derived from A or A itself , I should be able to create only one object per class using new keyword. If I try to creating another object it will throw exception.
Class B is derived class of A similarly class C, D, E are also derived classes. The number of class is not limited. Any number of classes can be derived.
The logic of restriction must be inside the class heirarchy not inside the main class.
Sample code of main class.
A obj1 = new A(); // object should create
A obj2 = new A(); // exception should throw
E Obj3 = new E(); //object should create
E obj4 = new E(); //Exception should throw
You can achieve that by storing a static reference to a collection holding instantiated classes (could be any data structure that works), then checking it in the constructor to avoid multiple instantiations:
class A {
private static Set<String> instantiatedClasses = new HashSet<>();
A() {
super();
if (instantiatedClasses.contains(getClass().getName())) {
throw new IllegalStateException(
"Cannot create multiple instances of " +getClass().getName());
}
instantiatedClasses.add(this.getClass().getName());
}
}
class B extends A {
}
And when that's tested:
A a = new A();
System.out.println("Created a: " + a);
try {
a = new A();
} catch (Exception e) {
e.printStackTrace();
}
a = new B();
System.out.println("Created b: " + a);
a = new B();
An output like this is produced:
Created a: stackoverflow.A#506e1b77
java.lang.IllegalStateException: Cannot create multiple instances of stackoverflow.A
at stackoverflow.A.<init>(Main.java:32)
at stackoverflow.Main.main(Main.java:14)
Created b: stackoverflow.B#9807454
Exception in thread "main" java.lang.IllegalStateException: Cannot create multiple instances of stackoverflow.B
at stackoverflow.A.<init>(Main.java:32)
at stackoverflow.B.<init>(Main.java:40)
at stackoverflow.Main.main(Main.java:21)
This is just exploiting the fact that a superclass's constructor is always invoked on instance creation for subclasses. And this will work even for arbitrary inheritance depths.
There are alternative ways of keeping track of classes that have been instantiated, one of which is storing the class, but I believe the necessary part is checking the type in the constructor (where the runtime classes can be seen, and before too late to prevent successful instantiation)
In class A: have a static set of class. Each time the constructor of A is invoked, use this.getClass() to acquire the actual class that wants to be instantiated (keep in mind that any sub class has to call a super constructor first).
If the class is stored in the set, throw that exception. If not, then store the class.
public class A {
private static final Set<Class<? extends A>> INSTANCE_HOLDER = new HashSet<>();
public A() {
if (INSTANCE_HOLDER.contains(this.getClass()))
throw new RuntimeException("can't create more than one instance.");
INSTANCE_HOLDER.add(this.getClass());
}
}
This should be enough to get you started.
For the record: although this should work, it seems like a rather odd idea. If you need singleton objects, rather look into using enums for example. That will prevent all the subtle issues, for example due multiple threads creating objects.
Or, as pointed out by the comment: what about the life time of these objects? You could use a map to ensure that references to your singletons are kept.
But in the end, all of this sounds like violations of the single responsibility principle.
You can use a static instance in A and then in the constructor check if an instance exists and if yes then throw an exception , if it does not then create an object. I am assuming that there is only one object of any class that is either A or a subclass of A. If you mean to say that there should be only instance for each subclass and A , then you may need to create a static HashMap with class Names as the key in A and then check if an instance exists for the particular class by checking for the className from the HashMap.
I have 2 Classes, A and B. Class A has some fields, one of them being an ArrayList<B>. Now, B has some fields of its own(their type&content is not relevant to the problem)
I know how to get the fields of A, and display their value, but I have been unable to find a solution that would enable me to also get the fields of B, from the ArrayList<B> declared in A.
Basically, I'm trying to print the content of each A, including the content of the ArrayList<B>. By content I mean pairs of attributes/fields .
It is assumed I know nothing of A and B ---> I have to write something very generic. Managed to make it work using reflection until I got to the issue described earlier.
Any ideas?
What's wrong with:
final A a = new A();
for (final Field f : a.getClass().getDeclaredFields()) {
f.setAccessible(true);
System.out.println(f.get(a));
}
This loops over all fields in A and prints the content. List has a nice toString method so you just need to have a toString method in B and it should work just fine.
If for some reason you cannot do that then recursion would work. This is dangerous however as, unless you know B does not have a reference at A somewhere, you will end up in an infinite loop.
void printMethods(final Object input) {
for (final Field f : input.getClass().getDeclaredFields()) {
f.setAccessible(true);
if (Collection.class.isAssignableFrom(f.getType())) {
final Collection<?> c = (Collection<?>) f.get(input);
for (final Object obj : c) {
printMethods(obj);
}
} else {
System.out.println(f.get(input));
}
}
}
It's a simple as this:
"Bs: " + a.bList();
B should override toString() too
Say if I have a class named Car I can use the following line of code in certain situations.
Car.class
My question is there a way I can make the same type of call if a user supplies a class name at run time. Have tried something similar to the below but no joy, is there a way i can do it.
String className = "Car";
Class.forName(className ).class;
Also I need to be able to cast dynamically, if the user specifies a list of objects I need to be able to dynamically cast.
e.g. instead of Car myCar = (Car) object
I need to be able to have to the user specify the name/type of class at run time so that I need to be able to do something along the lines of ClassName myObj = (ClassName) object.
Class.forName("Car") already returns the same as Car.class.
For casting, you can then use Class.forName("Car").cast(object), which would return a Car object. Take a look at the API, mostly the java.lang.Class part of it.
Also, since you're casting # runtime, there's no type safety, and you should check whether object extends or implements Car before doing it, otherwise you'll get an exception. A question I asked ~ a year ago and the answers there may be relevant to you as well.
Though, as others already said, this smells & you could probably redesign it in a better way, also note that this type of casting will typically be pretty slow because Java needs to examine the type hierarchy (it needs to throw a ClassCastException if it can't cast to Car).
Given the nature of the question, most of the answers to this are straight from the Reflection API documentation. I would suggest you take a look at this: http://docs.oracle.com/javase/tutorial/reflect/class/index.html. If this does not help and you need help with something specific, we can look at that.
What you are looking for is a feature called Reflection in the Java programming language.
It allows an executing Java program to examine or "introspect" upon itself, and manipulate internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members and display them.
A Simple Example from http://java.sun.com
import java.lang.reflect.*;
public class DumpMethods {
public static void main(String args[])
{
try {
Class c = Class.forName(args[0]);
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
System.out.println(m[i].toString());
}
catch (Throwable e) {
System.err.println(e);
}
}
}
For an invocation of:
java DumpMethods java.util.Stack
the output is:
public java.lang.Object java.util.Stack.push(
java.lang.Object)
public synchronized
java.lang.Object java.util.Stack.pop()
public synchronized
java.lang.Object java.util.Stack.peek()
public boolean java.util.Stack.empty()
public synchronized
int java.util.Stack.search(java.lang.Object)
Here is an example of creating objects at runtime:
import java.lang.reflect.*;
public class constructor2 {
public constructor2()
{
}
public constructor2(int a, int b)
{
System.out.println(
"a = " + a + " b = " + b);
}
public static void main(String args[])
{
try {
Class cls = Class.forName("constructor2");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Constructor ct
= cls.getConstructor(partypes);
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj = ct.newInstance(arglist);
}
catch (Throwable e) {
System.err.println(e);
}
}
}
You can read more about it here and here - for indepth view
Also look here:
What is reflection and why is it useful?
You want to interact with myObj, so rather than going through these gymnastics, think about adding an interface that models the interactions you want to have with the objects, then use that interface in the code. The classes supplied by the user can then be validated to implement the necessary interface and errors raised appropriately.
The expression Car.class returns the java.lang.Class object for class Car.
A statement Class.forName("Car") will also return the java.lang.Class object for class Car (assuming that class Car is in the default package). Note: No need to append .class; that would give you the Class object of class Class itself, which is not what you want.
Class Class has methods to check if an object is an instance of the class that the Class instance represents (hope this is not too confusing...). Since you don't know the name of class Car at compile time, you're not going to have any kind of compile time type safety.
Lookup the API documentation of java.lang.Class.
I use a class that makes my Hibernate Query through a FilterCriterionList (sort of finder) and it's always worked perfectly until now and triggers a NullPointerException and I have absolutely no idea as to why it's triggered.
This is the method (in ReflectionUtil) that triggers the nullpointer with the following values (mind you that the other values thrown at it work perfectly and it's just these that seem to give an error):
type = interface java.util.List
fieldName = parameter
First it throws the NoSuchFieldException and on it's second run (as it's called again at field = getField(type.getSuperclass(), fieldName);) makes it throw a NullPointerException and just stop dead (all of this happens in my UnitTest, not a live environment yet).
public static Field getField(Class type, String fieldName) {
Field field = null;
try {
field = type.getDeclaredField(fieldName);
} catch (Exception e) {
if (!type.equals(Object.class)) {
field = getField(type.getSuperclass(), fieldName);
}
}
return field;
}
Any ideas as to why this happens (or what I can do to fix it?). I can't really show off more code as it's quite complicated and it's company code.
java.util.List is an interface, therefore calling getSuperclass() on it results in null.
The correct way to apply getField() recursively is the following:
} catch (Exception e) {
Class superclass = type.getSuperclass();
if (superclass != null) {
field = getField(superclass, fieldName);
}
}
You called like this:
getField(List.class, "parameter");
It would have never worked as List is an interface and it doesen't have any field called parameter. For the second call, its' null because interface List doesnet have a superclass.
From the Class.getSuperclass documentation
Returns the Class representing the
superclass of the entity (class,
interface, primitive type or void)
represented by this Class. If this
Class represents either the Object
class, an interface, a primitive type,
or void, then null is returned. If
this object represents an array class
then the Class object representing the
Object class is returned.
Say I have a class:
public class R {
public static final int _1st = 0x334455;
}
How can I get the value of the "_1st" via reflection?
First retrieve the field property of the class, then you can retrieve the value. If you know the type you can use one of the get methods with null (for static fields only, in fact with a static field the argument passed to the get method is ignored entirely). Otherwise you can use getType and write an appropriate switch as below:
Field f = R.class.getField("_1st");
Class<?> t = f.getType();
if(t == int.class){
System.out.println(f.getInt(null));
}else if(t == double.class){
System.out.println(f.getDouble(null));
}...
R.class.getField("_1st").get(null);
Exception handling is left as an exercise for the reader.
Basically you get the field like any other via reflection, but when you call the get method you pass in a null since there is no instance to act on.
This works for all static fields, regardless of their being final. If the field is not public, you need to call setAccessible(true) on it first, and of course the SecurityManager has to allow all of this.
I was following the same route (looking through the generated R class) and then I had this awful feeling it was probably a function in the Resources class. I was right.
Found this:
Resources::getIdentifier
Thought it might save people some time. Although they say its discouraged in the docs, which is not too surprising.
I was looking for how to get a private static field and landed here.
For fellow searchers, here is how:
public class R {
private static final int _1st = 0x334455;
}
class ReflectionHacking {
public static main(String[] args) {
Field field = R.class.getFieldDeclaration("_1st");
field.setAccessible(true);
int privateHidenInt = (Integer)field.get(null);
}
}