Lets start with a few basics:
A simple name of a class is just the one word name of the class, not the full class name. For example the class java.lang.Object can be referred to by its simple name of Object. A non final class is a class whose declaration does not contain the keyword final. The following is a final class declaration:
public final class Test { }What exactly is a class instance creation expression? Basically it is any expression who's desired result is the creation of a new instance of a class. They can appear in one of two main forms, qualified or unqualified.
An unqualified expression has the form:
new ClassOrInterfaceType ( ArgumentListopt ) ClassBodyopt
The keyword new is, of course, the key word new. The ClassOrInterfaceType is the type of the class being created. If, for example, you have a class named MyClass,an unqualified creation expression for an instance of this class would look like:
new MyClass( );You can use an unqualified expression to create any type of class instance you desire.
A qualified expression looks like this:
Primary.new Identifier ( ArgumentListopt ) ClassBodyopt
Qualified expression are used to create instances of inner classes. The Primary part of the expression identifies the outer (enclosing) class. new is, again, the new keyword. Identifier is the simple name of the inner class being created. As an example, assume you have a class named Outer that has an inner class named Inner. The expression to create an instance of inner would look like:
new Outer( ).new Inner( );A qualified expression is used to create an instance of an inner class when there is no enclosing class instance present.
In both type of expressions the argument list is an option list of values passed tot he constructor that is called when the instance is created. Both types can also have an optional class body following the creation expression, if there is a class body then the creation expression is for an anonymous class. In all cases the type of the class being created must be accessible, see the JLS section 6.6.
Ok, all of that is great but what exactly does instantiated mean? Instantiated is simply when an instance of a class is created through a class instance creation expression. Want more detail? Ok, there are four basic steps that go into the creation of a class instance:
The two type of creation expression can be divided into two main groups – with and without a class body. As mentioned, if a class body follows the expression then an anonymous class is being created.
If the expression is unqualified then you are creating either an anonymous direct subclass of the class named in the ClassOrInterfaceType or an anonymous direct subclass of Object that implements the interface named.
In a qualified expression then you are creating an anonymous direct subclass of the class named in the Identifier. The class is an inner class that is a member of the class specified as the Primary.
In both cases the class being subclassed must be non-final and accessible.
If the expression is not for anonymous class then an unqualified expression creates an instance of the class named in the ClassOrInterfaceType. And a qualified expression creates a class of the type identified by Identifier. The type named by the Identifier must be an inner class of the class named in Primary. In either case the class being created must not be abstract, it must be accessible, and for inner classes the Identifier must be a simple name of the class.
Determine the enclosing instances
This only applies to inner classes (non-static member classes). If you are creating an instance of an inner class then that instance is associated with an instance of the enclosing class. This is called the enclosing instance. There are several steps to determine what the enclosing instances are.
If the class being created is an anonymous class:
public class Test { public static void main(String args[]) { Test t = new Test(); t.testMeth(); } public void testMeth() { Inner in = new Inner(); } class Inner { } }In the method testMeth a new instance of the inner class Inner is being created its enclosing instance is the implied this that is passed to the method, it is an instance of the class Test. If the class being created is a local class (it is declared inside of a method inside of another class):
public class Test { public static void main(String args[]) { Test t = new Test(); t.testMethod(); } public void testMethod() { Outer o = new Outer(); o. innerTest(); } } class Outer { public void innerTest() { class Inner{}; Inner i = new Inner(); } }The member class Inner is defined in the class Outer, so in the method innerTest when an instance of class Inner is created it enclosing class instance is the instance of Outer that the method is invoked with. If the class being created is not an anonymous class and it's not a local class then it is just a plain old regular member class – a nested class not declared static and not defined in a method.
class Outer { public Outer() { Inner i = new Inner(); } class Inner { class Inner2 { class Inner3 { public Inner3() { Inner2 i2 = new Inner2(); } } } } }In this example an instance of Inner2 is created within the class Inner3. The actual enclosing object of the instance being created is an instance of class Inner. Which instance of Inner? What essentially happens is that the compiler determines the type of the class that is the enclosing instance (Inner, in this case) and counts how many levels up from the class that has the creation expression in it. In this example Inner is 2 levels up from Inner3. Then the compiler takes a look at the actual objects involved. It looks at the this object involved in the expression – in this example it is an object of type Inner3. Then it goes up the same number of this objects to find the enclosing instance. We found that the class Inner is 2 levels up from Inner3, so the compiler finds the enclosing instance of the this object in the creation expression (this takes us up one level) which is an Inner2 object. Then it finds the enclosing instance of that object (this is up a 2nd level) and it happens to be an Inner object.
Otherwise a compiler error will occur.
If the creation expression is a qualified expression, like this:
In most cases you don't need to know how the compiler finds the exact object, but it can be very helpful to know what type of object you'll get when you refer to an objects enclosing instance.
Choosing the Constructor and its Arguments
When an object is created we all know the appropriate constructor is called to build the object. The constructor is chosen at compile time and must be a constructor for the class being created. The first thing done is that the actual arguments must be figured out. Any expressions must be fully evaluated and must complete normally (they don't throw an exception). Then, in most cases*, the arguments in the list are the ones that are given to the constructor in the order they appear in the list. Once the arguments are determined the exact constructor is determined by the compiler using the same rules for method invocation described in the JLS section 15.12
*The special case would be if the class being created were an anonymous sub-class of a class that is non-static member of another class.
Written by Dave Vick