5

Simple question but I have spent over an hour with this. My code is below. I need to make SomeClass sc dynamic. So you pass the class name as a string in a function and use that class in place of static someClass. How to go about it?

SomeClass sc;
if (someOtherClassObject instanceof SomeClass){
    sc=(SomeClass) someOtherClassObject;

What I want is

public void castDynamic (String strClassName){
  //cast the classname referred by strClassName to SomeClass 
  //if it is the  instance of SomeClass
}

EDIT: The above was simplification. The actual code is this

public void X(String className, RequestInterface request)
{
    //My current code is this, I need to change so that "XRequest"
    //can be any   class referred by "className", 
    //and "request.getRequest" the object belonging to "className" class
    //I don't want static XRequest xvr, it should be fetched dynamically

    XRequest xvr;
    if (request.getRequest() instanceof XRequest){
        xvr=(XRequest) request.getRequest();
        client.setRequest(xvr); 
    }
}

Another simple rephrase: I get an object using request.getRequest(). I have no clue what that object is. So I need to cast it to the classstring name provided. How to do that? That's all. – SQC 13 mins ago

Morteza Soleimani
  • 2,652
  • 3
  • 25
  • 44
SQC
  • 591
  • 3
  • 9
  • 18
  • 2
    Perhaps you should describe your desired result in your question. Creating an instance of a class based on a string has nothing to do with dynamic casting. Do you want to create an instance of a known class starting with a string class name or do you want to create an instance of any class starting with a string class name? – DwB Dec 12 '11 at 20:11
  • please see updated question (even if it's a bit confusing). What I am creating is an api call which receives classname, and an object of the same classname. I need to cast the object to the classname in the method (but remember I have only the string for classname, not the real class). That's all. Simple. – SQC Dec 12 '11 at 20:39
  • The proper way would be to put that Method into the `RequestInterface`, then you can easily call it. Other than that, you need to use **reflection** to retrieve a method to invoke. – Has QUIT--Anony-Mousse Dec 12 '11 at 21:13

3 Answers3

8

You want to instantiate a class by it's name?

First of all, you need to make a Class<?> object:

Class<?> cls = Class.forName(strClassName);

Then instantiate this (note, this can throw various exceptions - access violation, ClassNotFound, no public constructor without arguments etc.)

Object instance = cls.newInstance();

Then you can cast it:

return (SomeClass) instance;

Please make sure you understand the differences between:

  1. A class name (approximately a file name)
  2. A class object (essentially a type information)
  3. A class instance (an actual object of this type)

You can also cast the cls object to have type Class<? extends SomeClass>, if you want. It doesn't give you much, though. And you can inline it, to:

return (SomeClass)(Class.forName(strClassName).newInstance());

Oh, but you can do type checking with the cls object, before instantiating it. So you only instanciate it, if it satisfies your API (implements the interface you want to get).

EDIT: add further example code, towards reflection.

For example:

if (cls.isInstance(request)) {
  // ...
}

For invoking methods, you either need to know an interface that you can cast to, or use reflection (the getMethod methods of the cls object):

Method getRequest = cls.getMethod("getRequest");
getRequest.invoke(request);
Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194
7

The problem you're describing is not well defined. Casting is an operation that takes an object and a Class and then checks if that object is an instance of the given class.

However you're saying you need something that cast(s) the classname referred by strClassName to SomeClass if it is the instance of SomeClass. In other words, you're looking something that works on two classes (rather than a class and an object).

So, we need to restate the problem. Here are three possible problems (+ solutions) I'm hoping one of them is what you need

// Problem 1: check whether "object" can be casted to the class 
// whose name is "className"
public void castDynamic(Object object, String className) {
  Class cls = Class.forName(className);
  cls.cast(object);
}

// Problem 2: check whether the class whose name is "className" 
// is a subclass of SomeClass (A is a subclass of B if A (transitively) 
// extends or implements B).
public void castDynamic(String className) {
  Class cls = Class.forName(className);
  SomeClass.class.asSubclass(cls);
}


// Problem 3: check whether SomeClass is a sublcass the class 
// whose name is "className"
public void castDynamic(String className) {
  Class cls = Class.forName(className);
  cls.asSubclass(SomeClass.class);
}

Full details: http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#asSubclass(java.lang.Class)

Itay Maman
  • 30,277
  • 10
  • 88
  • 118
1

Do you mean?

 Class clazz = Class.forName(strClassName);
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Th error is caused by the two lines below that cast. How would you code the "if (){}" part? – SQC Dec 12 '11 at 20:03
  • What is your end goal? When you cast objects this way its because you need to use an instance of that class for something. – Peter Lawrey Dec 12 '11 at 20:07