I have a String which has a name of a class say "Ex" (no .class extension). I want to assign it to a Class variable, like this:
Class cls = (string).class
How can i do that?
Class<?> cls = Class.forName(className);
But your className should be fully-qualified - i.e. com.mycompany.MyClass
String clsName = "Ex"; // use fully qualified name
Class cls = Class.forName(clsName);
Object clsInstance = (Object) cls.newInstance();
Check the Java Tutorial trail on Reflection at http://java.sun.com/docs/books/tutorial/reflect/TOC.html for further details.
You can use the forName method of Class:
Class cls = Class.forName(clsName);
Object obj = cls.newInstance();
You can get the Class reference of any class during run time through the Java Reflection Concept.
Check the Below Code. Explanation is given below
Here is one example that uses returned Class to create an instance of AClass:
package com.xyzws;
class AClass {
public AClass() {
System.out.println("AClass's Constructor");
}
static {
System.out.println("static block in AClass");
}
}
public class Program {
public static void main(String[] args) {
try {
System.out.println("The first time calls forName:");
Class c = Class.forName("com.xyzws.AClass");
AClass a = (AClass)c.newInstance();
System.out.println("The second time calls forName:");
Class c1 = Class.forName("com.xyzws.AClass");
} catch (ClassNotFoundException e) {
// ...
} catch (InstantiationException e) {
// ...
} catch (IllegalAccessException e) {
// ...
}
}
}
The printed output is
The first time calls forName:
static block in AClass
AClass's Constructor
The second time calls forName:
The class has already been loaded so there is no second "static block in AClass"
The Explanation is below
Class.ForName is called to get a Class Object
By Using the Class Object we are creating the new instance of the Class.
Any doubts about this let me know
It should be:
Class.forName(String classname)
Not sure what you are asking, but... Class.forname, maybe?
public static Class<?> getType(String typeName) {
if(typeName.equals("Date")) {
return Date.class;
} else if(typeName.equals("Float")) {
return Float.class;
} else if(typeName.equals("Double")) {
return Double.class;
} else if(typeName.equals("Integer")) {
return Integer.class;
}
return String.class;
}
Related
I have a super class A, and classes B, C and D that extend A.
class A {}
class B extends A {}
class C extends A {}
class D extends A {}
Then I have a list like this:
[B.class, C.class, D.class]
I take a random item from the list and instantiate it like so:
Object obj = list.get(i).newInstance()
Now I need to pass obj to a method that accepts objects of type A as a parameter.
A a = (A) obj
causes java to throw an exception (Either InstantiationException or IllegalAccessException, I don't know because android studio won't stop at breakpoints inside the catch, and any attempt to save information about the exception from the catch results in null...).
I understand why I can't dynamically specify the new object type and then cast obj to that type, but if they all share the common parent, I don't see why it wouldn't work.
Can anybody enlighten me how to fix what I'm currently doing, or achieve the same thing in a similar way?
Thanks! /Max
The newInstance method can throw an InstantiationException or IllegalAccessException, hence the warning you're probably seeing in your IDE if this call isn't wrapped in a try/catch. Your simple example seems to work fine though.
class A {}
class B extends A {}
class C extends A {}
public class Test {
public static void main(String[] args) throws Exception {
List<Class> list = new LinkedList<Class>();
list.add(B.class);
list.add(C.class);
Object obj = list.get(0).newInstance();
A a = (A) obj;
System.out.println(a instanceof B);
}
}
Prints "true"
In the end this was due to a bug with android studio. Rewriting the code fixed the problem and I wasn't able to reproduce this issue
Other symptoms that future searchers might find useful:
android studio would not stop at breakpoints inside a catch block
Any attempt to save information about the exception inside the catch resulted in null (see example below)
:
Exception ex = null;
try {
// do something that raises an exception
ex = new Exception();
} catch (Exception ex) {
ex = ex;
}
// ex == null
As pointed out by the other answers, what I was describing in my question does not normally raise an exception.
The code seems to be working absolutely fine. I am not understanding your question.
package testplayground;
import java.util.ArrayList;
import java.util.List;
class A {
void print() {
System.out.println("inside A");
}
}
class B extends A {
public void print() {
System.out.println("inside B");
}
}
class C extends A {
public void print() {
System.out.println("inside C");
}
}
class D extends A {
public void print() {
System.out.println("inside D");
}
}
public class TestPlayGround {
public static void main(String[] args) {
try {
List<Class> list = new ArrayList<Class>();
list.add(B.class);
list.add(C.class);
list.add(D.class);
for (Class classObj : list) {
Object obj = classObj.newInstance();
A a = (A) obj;
methodA(a);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void methodA(A a) {
a.print();
}
}
output:-
inside B
inside C
inside D
Say I have two classes
class parentClass{
String myElement;
}
class childClass extends parentClass{
String notMyElemtent;
}
Now say there is an object of class childClass. Is there a way programatically tell that myElement in that object belongs to parentClass originally??
You can do it with reflection. Use obj.getClass().getField("myElement") to get Field object, representing your field.
Now you can use getDeclaringClass() method of Member interface to get class or interface actually declaring this member. So do something like this
childClass obj = new childClass();
Field field = obj.getClass().getField("myElement");
if (field.getDeclaringClass().equals(parentClass.class)) {
// do whatever you need
}
Is there a way to tell that myElement in that object belongs to parentClass originally?
Yes, you can use reflection to examine the fields of the super class:
Use Class.getSuperClass() to get the super class
Then, use
Class.getDeclaredFields() on the returned class from the above call to get a list of all fields declared by the super class
Class.getDeclaredField(String fieldName) to directly check the existence of a given field
In code, this could look like:
public static boolean belongsToParent(Object o, String fieldName) {
Class<?> sc = o.getClass().getSuperclass();
boolean result = true;
try {
sc.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
result = false;
}
return result;
}
public static void main(String[] args) {
childClass cc = new childClass();
System.out.println("myElement belongs to parentClass: " +
belongsToParent(cc, "myElement"));
System.out.println("notMyElemtent belongs to parentClass: " +
belongsToParent(cc, "notMyElemtent"));
}
Output:
myElement belongs to parentClass: true
notMyElemtent belongs to parentClass: false
Well, use getDeclaredField(name) of a class, and if its not there, try looking at its super class and so on. Works for multiple levels of inheritance:
Class<?> clazz = childClass.class;
do {
try {
Field f = clazz.getDeclaredField(fieldName);
//there it is! print the name of the super class that holds the field
System.out.println(clazz.getName());
} catch (NoSuchFieldException e) {
clazz = clazz.getSuperclass();
}
} while (clazz != null);
import java.lang.reflect.Field;
public class Test4 {
public static void main(String[] args){
Child child = new Child();
System.out.println(getDeclaringClass(child.getClass(), "value"));
}
public static String getDeclaringClass(Class<?> clazz, String name) {
try {
Field field = clazz.getDeclaredField(name);
} catch (NoSuchFieldException e) {
if(clazz.getSuperclass() != null){
return getDeclaringClass(clazz.getSuperclass(), name);
}else{
return null;
}
}
return clazz.getName();
}
}
class Parent {
String value = "something";
}
class Child extends Parent {
}
This question already has answers here:
How can a derived class invoke private method of base class?
(7 answers)
Closed 7 years ago.
public class A{
private int getC(){
return 0;
}
}
public class B extends A{
public static void main(String args[]){
B = new B();
//here I need to invoke getC()
}
}
Can you please tell me if it is possible to do sush thing via reflection in java?
class A{
private void a(){
System.out.println("private of A called");
}
}
class B extends A{
public void callAa(){
try {
System.out.println(Arrays.toString(getClass().getSuperclass().getMethods()));
Method m = getClass().getSuperclass().getDeclaredMethod("a", new Class<?>[]{});
m.setAccessible(true);
m.invoke(this, (Object[])null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
EDIT:
This is quiet an old post but adding a few nuggets of advice
Reconsider your design
Calling private method of parent, though possible through Reflection, but should not be done. Calling private methods on parent might leave the class in invalid state and may lead to unexpected behaviors.
You can do it using reflection, but unless there is a very good reason to do so, you should first reconsider your design.
The code below prints 123, even when called from outside A.
public static void main(String[] args) throws Exception {
Method m = A.class.getDeclaredMethod("getC");
m.setAccessible(true); //bypasses the private modifier
int i = (Integer) m.invoke(new A());
System.out.println("i = " + i); //prints 123
}
public static class A {
private int getC() {
return 123;
}
}
You should declare getc protected. That's exactly what it's for.
As for reflection: Yes, it is possible. You'd have to call setAccessible on the method object though. And it's bad style... ;-)
getDeclaredMethod will only return the private methods in the current class not the inherited methods. To achieve it you need to navigate the inheritance graph via the getSuperclass method. Here is a code snippet that does it
private Method getPrivateMethod(Object currentObject) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class<?> currentClass = currentObject.getClass();
Method method = null;
while (currentClass != null && method == null) {
try {
method = currentClass.getDeclaredMethod("getC");
} catch (NoSuchMethodException nsme) {
// method not present - try super class
currentClass = currentClass.getSuperclass();
}
}
if (method != null) {
method.setAccessible(true);
return method;
} else {
throw new NoSuchMethodException();
}
}
you can try like this using reflection:
Method getCMethod = A.class.getDeclaredMethod("getC");
getCMethod.setAccessible(true);
getCMethod.invoke(new A());
A normal form of what I am trying is this.
MyClassFacadeLocal cls = new MyClassFacadeLocal();
List allMyClass = cls.findAll();
Iterator it = allMyClass.iterator();
while(it.haxNext()) {
MyClass Obj = (MyClass)it.next();
out.println(obj.getTitle());
}
Now, the problem I am creating a global method, which can handle several cases of this. For this, I will pass the Entity Class name, method name and the List that is return by the .findAll() method. How to solve this using the reflection. What I tried was really rough and of course didn't work.
List allMyClass; //I will have passed this before
Iterator it = allMyClass.iterator();
while(it.hasNext()) {
try {
Class<?> c = Class.forName(this.getEntityClassName());
c.cast(it.next());
Method method = c.getDeclaredMethod("getTitle");
String title = method.invoke(c, null).toString();
} catch(Exception e) {
}
}
Gives: "object is not an instance of declaring class" error. But I am confident this is a usage flaw.
Really, you shouldn't use reflection to do that. Make all your entities implement a common interface with a getTitle() method:
public interface HasTitle {
public String getTitle();
}
public class MyClass1 implements HasTitle {
// ...
#Override
public String getTitle() {
return this.title;
}
}
public class MyClass2 implements HasTitle {
// ...
#Override
public String getTitle() {
return this.title;
}
}
...
/**
* This method can be invoked withg a List<MyClass1> or with a List<MyClass2>
* as argument, since MyClass1 and MyClass2 both implement HasTitle
*/
public void displayTitles(List<? extends HasTitle> entities) {
for (HasTitle entity : entities) {
out.println(entity.getTitle();
}
}
Your code does too much work by using Class.forName and uses the wrong reflection method getDeclaredMethod -- that one doesn't take into account the inherited methods. The c.cast line doesn't do anything -- it merely asserts that the object is an instance of its own class.
Use this code:
public static void printProp(List<?> xs, String methodName) {
try {
for (Object x : xs)
System.out.println(x.getClass().getMethod(methodName).invoke(x));
} catch (Exception e) { throw new RuntimeException(e); }
}
The first glance flaw I see is that you don't assign the
c.cast(it.next());
to new variable.
The Object.clone() method in Java is pretty special, as instead of returning a copy of the object that is to be cloned with the Object type, it returns the correct Object type. This can be better described with the following code:
class A implements Cloneable
{
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class B extends A {
}
public class MainABC {
public static void main(String[] args) throws CloneNotSupportedException {
B b = new B();
B b1 = (B)b.clone(); //see here that we are using A's .clone(). The only
//thing it does is call Object's clone().
System.out.println(b1.getClass()); //but as we see here, its not an Object
//its a B!
}
}
So, could anyone explain if possible if is there anyway to replicate what happens inside Object.clone()'s method?
It is definitely true that Object.clone() does a few things that simply can not be achieved in Java.
From Josh Bloch on Design: Copy Constructor versus Cloning (emphasis mine):
Object's clone method is very tricky. It's based on field copies, and it's "extra-linguistic." It creates an object without calling a constructor. There are no guarantees that it preserves the invariants established by the constructors.
Object.clone() does something that isn't supposed to be allowed by the language. That is why, among many other reasons, clone() is broken.
(If you haven't already, you should also read his book Effective Java, to understand why he (and many others) think that Java's clone() and Cloneable is broken).
If you just want to create an object of the same class as another arbitrary object, then this is actually quite achievable, with some caveat (namely that not all types are publicly instantiable) by using reflection.
Here's an example of how to use reflection to:
Find out the class of an object at run-time
List its declared fields, methods, and constructors
Find its copy constructor (if any), and tries to invoke it using the given object as
parameter.
import java.lang.reflect.*;
public class NewInstance {
static void print(String label, Object[] arr) {
System.out.println(label);
for (Object o : arr) {
System.out.println(o);
}
System.out.println("---");
}
static Object newInstance(Object o) {
Class<?> c = o.getClass();
System.out.println("Class is " + c);
print("FIELDS:", c.getDeclaredFields());
print("METHODS:", c.getDeclaredMethods());
print("CONSTRUCTORS:", c.getDeclaredConstructors());
try {
Constructor<?> cc = c.getDeclaredConstructor(c);
o = cc.newInstance(o);
} catch (NoSuchMethodException e) {
System.out.println("No copy constructor found!");
} catch (IllegalAccessException e) {
System.out.println("Copy constructor inaccessible!");
} catch (InstantiationException e) {
System.out.println("Instantiation failed!");
} catch (InvocationTargetException e) {
System.out.println("Copy constructor threw " + e.getCause());
}
return o;
}
public static void main(String args[]) {
Object o1 = "hello";
Object o2 = newInstance(o1);
boolean success = (o1 != o2) && (o1.equals(o2));
System.out.println("Attempt " + (success ? "succeeded!" : "failed :("));
}
}
Output:
Class is class java.lang.String
FIELDS:
// (omitted)
METHODS:
// (omitted)
CONSTRUCTORS:
public java.lang.String()
public java.lang.String(java.lang.String) // this is what we're looking for!
// (rest omitted)
---
Attempt succeeded!
Note that this is just an example to show type can be inspected at run time and a copy constructor can be looked for and invoked. As is, it doesn't work if o is an ArrayList, because it has no constructor that takes an ArrayList (it does have one that takes a Collection, which an ArrayList is).
I'll leave it to you as an exercise on how to expand the search for the copy constructor to include these compatible overloads.
I've never heard or seen a language construct that provides you the functionality that clone give you for free.
You can imitate it, but I don't believe you can replicate the behavior.
The Objenesis library can be used to create instances of arbitrary classes even if they do not have a no-args constructor. It uses various tricks for each JVM to accomplish this. You can use that together with a bit of reflection code to copy all field values from the source object to the destination.
I think you have not even tested the code you typed here!
If you try to compile this code you get errors. First of all the return super.clone() gives you an error of "Type mismatch: cannot convert from Object to A"
Second (i will assume this was a mistype) you did not create an instance of B. You said
B = new B();
Even if we change that to
B b = new B();
B b1 = b.clone();
You will get an error because b.clone() will return an instance of class A.
So sorry but you describe does not happen... You need a cast to get what you want.
So to sum up:
public class A extends Object {
public A clone() {
return super.clone(); // Error "Type mismatch: cannot convert from Object to A"
}
public static void main(String[] args) {
B b = new B();
B b1 = b.clone(); // Error "Type mismatch: cannot convert from A to B"
}
}
class B extends A {
}
EDIT: I'm afraid you got it wrong again. What you did returns an instance of B because you cast it to a B instance. It would return B even if you cast something completely different... For instance
B b = (B)(new JLabel());
System.out.println(b.class);
This will print the class of B. Actually it WOULD print the class of B if it ever got there... You will get an exception before it gets there... To have what you want you have to manually override the clone method and provide your own implementation. You question is not valid at all.. You should delete it but you can't since you have upvoted answers... I would vote to close at least...
How about this?
public class A {
public static void main(String[] args) {
B b = new B();
B b1 = (B)b.getNew();
System.out.println(b1.getClass());
}
public Object getNew() {
try {
return getClass().newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
class B extends A {
}