THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1
Uses the constructor represented by this Constructor object to create and
initialize a new instance of the constructor's declaring class, with the
specified initialization arguments. A reference to the newly initialized object
is returned. Constructor.newInstance is very similar to
Method.invoke. The number of args values must equal the number of
parameters for the constructor, and the types of those values must all be
assignable to those of the constructor. Otherwise you will get an
IllegalArgumentException. Again, note that for a varargs
constructor the last parameter is an array that you must fill in with the actual
"variable" arguments you want to pass. If the declaring class is abstract you
will get an InstantiationException. If the constructor is one to
which you do not have access, you will get an
IllegalAccessException. If the constructor itself throws an
exception, you will get an InvocationTargetException whose cause
is that exception.

If your constructor object is referenced through a wildcard reference, then you must cast the object returned
by newInstance to the right type.


Exercise 16.8: Modify your Interpret program further to let users invoke constructors of an arbitrary
class, displaying any exceptions. If a construction is successful, let users invoke methods on the returned
object.


16.8.1. Inner Class Constructors


An inner class (excluding local and anonymous inner classes) never has a no-arg constructor, since the
compiler transforms all inner class constructors to take a first parameter that is a reference to the enclosing
object. This means that you can never use Class.newInstance to create an inner class object, so you
must use Constructor objects. The Constructor objects for an inner class reflect the transformed
code, not the code written by the programmer. For example, consider the BankAccount class and its
associated inner Action class from page 136. The Action class had a single constructor that took a
String parameter, representing the action that had occurred (withdraw, deposit, and so on), and a long
value, representing the amount involved. If you use getdeclaredConstructors to obtain that
Constructor object and print its signature using toString, you will get the following:


BankAccount$Action(BankAccount,java.lang.String,long)


Here you can see both the use of the $ naming convention for inner classes and the implicitly added
constructor argument that refers to the enclosing object. You can retrieve this constructor as follows:


Class actionClass = Action.class;
Constructor con =
actionClass.getDeclaredConstructor(BankAccount.class,
String.class, long.class);


If you want to construct an Action object you must supply an appropriate enclosing object reference as in


BankAccount acct = new BankAccount();
// ...
Action a = con.newInstance(acct, "Embezzle", 10000L);

Free download pdf