user1230409
user1230409

Reputation: 1

Java run time class reflection

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.

Upvotes: 0

Views: 2614

Answers (5)

TC1
TC1

Reputation: 1

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).

Upvotes: 2

John Eipe
John Eipe

Reputation: 11228

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?

Upvotes: 1

Jesper
Jesper

Reputation: 206816

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.

Upvotes: 0

sw1nn
sw1nn

Reputation: 7328

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.

Upvotes: 0

Pavan
Pavan

Reputation: 1247

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.

Upvotes: 1

Related Questions