1

I have a Class object, clazz. I want to make the object of that type class.

i.e. Class clazz = MTable.getClass(tableName);

The variable clazz may be of type MOrder.class, MInventory.class, or MSalary.class. Now I want to make the object of MOrder for an instance. Without comparing the clazz with MOrder.class, how can I create object of MOrder. Is Java providing any such mechanism?

Update:

I tried this:

Class<? extends DocAction> clazz = (Class<? extends DocAction>) MTable.getClass(re.tableName);
        DocAction instance = null;
        try {
                instance = clazz.newInstance();
        } catch (InstantiationException e1) {
            e1.printStackTrace();
        } catch (IllegalAccessException e1) {
            e1.printStackTrace();
        }

But an exception is thrown:

java.lang.InstantiationException: org.compiere.model.MOrder

Eran
  • 387,369
  • 54
  • 702
  • 768
Sajeev
  • 783
  • 3
  • 14
  • 46
  • What do you want to do if you get `MInventory.class` or `MSalary.class`? Why not instantiate `MOrder` directly? – Joni Nov 12 '14 at 09:25
  • I have several classes; not only MInventory, MSalary or MOrder; So instantiate all those classes are difficult. Another hope is that, all those Classes are implemented an interface DocAction.class – Sajeev Nov 12 '14 at 09:52
  • So you want to instantiate other classes than MOrder, but not all classes? How do you decide whether to instantiate or not? Your error is probably caused by MOrder not having a default constructor by the way – Joni Nov 12 '14 at 10:04

3 Answers3

3

Try:

Object object = clazz.newInstance()
Jens
  • 67,715
  • 15
  • 98
  • 113
3
Object object = clazz.newInstance();

would create the instance based on the value of clazz.

If you want to store the object in a MOrder variable, you have to check its type first :

MOrder order = null;
if (object instanceof MOrder) {
    order = (MOrder) order;
}

You can't avoid the testing of the type, since as you said, clazz may contain different Class instances.

If all of your classes implement DocAction interface, you can do the following :

Class<? extends DocAction> clazz = ...
DocAction instance = clazz.newInstace();

This would at least give you a reference of the type of the interface. You would still need to check the specific type if you want to store the instance in a more specific variable.

Eran
  • 387,369
  • 54
  • 702
  • 768
  • `You can't avoid the testing of the type`. Thanks. But if I have n number of class types its difficult to check each and every one. There is a hope: all those classes implements an interface called `DocAction`, then is there any chance of getting the corresponding method declared in DocAction? – Sajeev Nov 12 '14 at 09:49
  • Thanks for your thought. I am getting the `java.lang.InstantiationException` – Sajeev Nov 12 '14 at 10:09
  • I have updated the question with the code which gives me the exception. – Sajeev Nov 12 '14 at 10:12
  • @Sej What is the value of `clazz` for which you get this exception? – Eran Nov 12 '14 at 10:12
  • it is the right one : `class org.compiere.model.MOrder` – Sajeev Nov 12 '14 at 10:13
  • @Saj some reasons for this exception : the class object (clazz) represents an abstract class, an interface, an array class, a primitive type, or void, or the class has no nullary constructor – Eran Nov 12 '14 at 10:14
  • @Saj Is `org.compiere.model.MOrder` a concrete (not abstact) class? And does it have a constructor with no parameters? – Eran Nov 12 '14 at 10:15
  • its a concrete class. But it do not have the constructur with no parameters – Sajeev Nov 12 '14 at 10:17
  • So I need to create the parameter based instance. Right? – Sajeev Nov 12 '14 at 10:17
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/64778/discussion-between-saj-and-eran). – Sajeev Nov 12 '14 at 10:17
  • @Saj newInstance invokes the constructor with no parameters, so it must exist. If your class has no constructors at all, the compiler will automatically generate a parameter-less constructor, but if you have a constructor with parameters, it won't. – Eran Nov 12 '14 at 10:18
  • I have the constructor as: MOrder(Properties ctx, integer PKey, Transaction trx). This is the common structure of all of the classes which implements DocAction – Sajeev Nov 12 '14 at 10:21
  • @Saj newInstance can't call your constructor. You must add a constructor `MOrder()` (no params) – Eran Nov 12 '14 at 10:23
  • Should I need to create a parameter less constructor? Or is there any other solution? Because I need to change the structure of all those classes. – Sajeev Nov 12 '14 at 10:23
  • How can we create parameter based constructure in this situation? – Sajeev Nov 12 '14 at 10:26
  • @Saj You have to create that constructor in order for clazz.newInstance() to work. – Eran Nov 12 '14 at 10:26
  • @Saj Using constructors with parameters would make the code more complicated - [see here](http://stackoverflow.com/questions/3671649/java-newinstance-of-class-that-has-no-default-constructor). – Eran Nov 12 '14 at 10:33
  • Yes. its slight complected. – Sajeev Nov 12 '14 at 11:18
  • I'm sure that you mean `order = (MOrder) object` instead, right?; – Makoto Nov 12 '14 at 21:10
1

@Saj, the Class object is not inherited by your classes, so MOrder.class or MInventory.class can't be type of Class object. All object inherits from Object class, and even Class object inherits from Object class. So, your logic seems incorrect. Think in terms other way to know which type of Object to create.

brb tea
  • 345
  • 1
  • 12