A way to use a string for creating new classes - java

I have a string with the name of a class, is there a way (writing in Java) to use that string when creating a new instance of that class, to do something like this:
object obj = new dataInString.
So the dataInString is parsed from the string.

Do you mean something like Class.forName(String)? Quoting the javadoc of the method:
Returns the Class object associated with the class or interface with the given string name. Invoking this method is equivalent to:
Class.forName(className, true, currentLoader)
where currentLoader denotes the defining class loader of the current class.
For example, the following code fragment returns the runtime Class descriptor for the class named java.lang.Thread:
Class t = Class.forName("java.lang.Thread")
A call to forName("X") causes the class named X to be initialized.
And then, call Class#newInstance() on the returned Class (it must have an empty constructor).
Creates a new instance of the class represented by this Class object. The class is instantiated as if by a new expression with an empty argument list. The class is initialized if it has not already been initialized.

Assuming that the class has a no-args constructor, then the following should do the trick
Class<?> clazz = Class.forName("someclass");
Object obj = clazz.newInstance();
If you need to create the object using a different constructor, then you will need to do something like this:
Constructor<?> ctor = clazz.getConstructor(ArgClass.class, Integer.TYPE);
Object obj = ctor.newInstance(arg, Integer.valueOf(42));
There are a number of checked exceptions that need to be handled in either case ...

You can use reflection.

Use reflections to instantiate objects. A simple class.forName("com.blah.blah") should be a good starting point to look for more information on reflections.

Related

Can we cast a object into a class type whose name is only known?

I have to dynamically fetch the tables whose names are available in dropdown in a jsp. Upon the selection of table name corresponding columns should be printed. For that I was running a loop in jsp and trying but is it possible to cast an object of "Object" type into a class whose class name is only known and after that using that object I have to acesss the corresponding class methods.
ex: className I got from jsp is "Book" and I have a class Book.class which has a method getName() so something like this is what I wanted:
Object obj1 = Class.forName(className).cast(obj);
obj1.getName();
Here obj is the object I have got through session.
forName takes a String and you can't call getMethod on Object because there is no such method. Ideally you'd have an interface defining the method that's common in all the types you can select from your drop down.
If that is not an option, then there is an uglier option using reflection where you don't actually need to know the type in advance:
Class<?> clazz = Class.forName("Book");
// Object obj1 = clazz.cast(obj);
// The method getName() is undefined for the type Object
Method m = clazz.getMethod("getName");
String res = (String) m.invoke(obj);
I'd not recommend using this code as is in any production application though. You'll need quite a bit of validation and exception handling in order to make this work safely.
Yes you can do that but the object must belong to that class or some of its child class else it will give you a ClassCastException. You also need to pass complete path of that class mean fully qualified class name with package.
Object obj1 = Class.forName(com.Book).cast(obj);
obj1.getName();

casting base class to derived class via reflection

Hi I have to construct an object from an object. Since the base class has more than 50 fields i dont want to do things like
//obj1 is an instance of BaseClass
DerivedClass obj2 = new DerivedClass();
obj2.setField1(obj1.getField1());
obj2.setField2(obj1.getField2())
.... so on
As you see from the title i want to downcast my object but java does not allow this. Is there a utility library or smth that provides a method like
Object convert(BaseClass obj1, DerivedClass obj2)
You can use Apache Commons BeanUtils to do this. Using its BeanUtils class you have access to a lot of utility methods for populating JavaBeans properties via reflection.
To copy all the common/inherited properties from a base class object to a derived class object you can use its static copyProperties() method as
BeanUtils.copyProperties(baseClassObj, derivedClassObj);
From the BeanUtils.copyProperties() docs
Copy property values from the origin bean to the destination bean for all cases where the property names are the same.
If you don't want to use a third-party library, your next best option would be to provide a utility method on the derived class that initializes itself with all the properties of an instance of its parent class.
public void initFromParent(BaseClass obj) {
this.propOne = obj.getPropOne();
// ... and so on
}
You can downcast if the cast is valid:
BaseClass instance = new DerivedClass();
if(DerivedClass.class.isAssignableFrom(instance.getClass()) {
DerivedClass dc = DerivedClass.class.cast(instance);
}
But normally one would implement a constructor with the same arguments and call super().
Or even better, use composition, where instead of inheritance you have DerivedClass hold an instance of BaseClass and delegate calls for the fields to that object.

How do i access a static member from my own custom class loader?

I have created my own custom class loader for loading a class to JVM. i can access the non static members using following code
MyLoader c=new MyLoader();
Class cls=c.loadClass("Hello");
Object obj=cls.newInstance()
cls.getMethod("show").invoke(obj);
But i don't know the procedure for accessing a static memebrs of a loaded class. Kindly provide a solution for this problem.
If you have static class members, you can access them just exactly calling from Class Class.myStaticMemeber. Static members also are called Class member, as you can call them directly from the class. Of course you can call them using the instance too, such as cls.myStaticMember, but you should remember that changing value of static member in one place will make this change to all places where you have called that static member.
// String.class here is the parameter type, that might not be the case with you
Method method = clazz.getMethod("methodName", String.class);
Object o = method.invoke(null, "whatever");
In case the method is private use getDeclaredMethod() instead of getMethod(). And call setAccessible(true) on the method object.
for static methods we can use null as instance of class

How do I typecast an object created through reflection to run a method?

I'm having trouble to find how to typecast the dynamically created class while using reflection.
String s;
...
Class unknownClass = Class.forName(s);
Constructor defaultConstructor = unknownClass.getConstructor(null);
Object retobj = defaultConstructor.newInstance(null);
retobj.Writeout(); // This won't work since;
The object class does not have a method called Writeout, but that is the name of the method which is shared by nine other possible classes that is dynamically created here (needless to say every Writeout method does a seperate thing). Any suggestions ? Thx in advance for your time.
Use reflection Luke...
Method writeOutMethod = unknownClass.getMethod("Writeout", new Class[]{});
writeOutMethod.invoke(retobj, new Object[]{});
Or, ensure that your objects implement a well known interface (the clean approach).
The 9 classes should all implement a single interface (let's call it Output) which declares the writeOut() method. The code would thus be:
Output retobj = (Output) defaultConstructor.newInstance(null);
retobj.writeOut();
Note that you could just use unknownClass.newInstance() to invoke the no-arg constructor.
Side note: please respect tha Java naming conventions: methods start with a lower-case letter.
Cast it:
((YourObjectWithThatMethod) retobj).Writeout();
EDIT (see the comment from Kevin Welker):
If all of your 9 classes implement the same interface, you can cast every class to that interface:
((YourInterface) retobj).Writeout();
If all nine classes share a super-class or an interface which declares/implements writeOut then you can cast retobj to that interface and then call it.
public interface Writable {
public void writeOut();
}
Then each class needs to have in the class declaration.
class MyClass implements Writable {
}
Then you can say
((Writable) retobj).writeOut();

How can I use a string to find the class that has the same name with the string

So, suppose I have a string str = "MyClass", now I want to use this str to find the MyClass so I can instantiate it, and use it.
Simple example:
MyClass obj = Class.forName("com.xyz.MyClass").newInstance();
This assumes the existence of a default constructor, and will throw various exceptions if the class cannot be found, or cannot be instantiated.
Class.forName may do what you want, but you will need the full package path as well.
Class myClass = Class.forName("package.MyClass");
Object instance = myClass.newInstance();
where package is the name of the package containing MyClass

Categories

Resources