如您所知,一个类为对象提供了设计图。您可以从类创建对象。从CreateObjectDemo程序中获取的以下每个语句都会创建一个对象,并将其分配给变量:
Point originOne = new Point(23, 94);
Rectangle rectOne = new Rectangle(originOne, 100, 200);
Rectangle rectTwo = new Rectangle(50, 100);
第一行创建Point类的对象, 第二行和第三行分别创建Rectangle类的对象 。
以上每一个语句中都包含三个部分(下面将详细讨论):

  1. 声明:以粗体设置的代码是将变量名称与对象类型相关联的所有变量声明。
  2. 实例化:new关键字是创建对象的Java运算符。
  3. 初始化:new运算符之后是对构造器的调用,该构造器将初始化新对象。

    声明变量以引用对象

    先前,您了解到要声明变量,您可以编写:
    1. type name;
    这将通知编译器您将使用name来引用类型为type的数据。对于基本类型变量,此声明还为该变量保留适当的内存。
    您也可以在其行上声明引用变量。例如:
    1. Point originOne;
    如果这样声明originOne,则在实际创建对象并将其分配之前,其值将不确定。仅声明引用变量不会创建对象。为此,您需要使用new运算符,如下一节所述。您必须先分配一个对象,然后originOne才能在代码中使用它。否则,您将得到编译器错误。
    处于这种状态的变量当前不引用任何对象,可以如下所示(变量名originOne,加上指向空的引用):
    创建对象 - 图1

    实例化一个类

    通过new创建一个新的对象(实例化一个类)以分配内存,并返回到内存的引用。new运算符还调用对象的构造器。

注意: 短语“实例化一个类”的含义与“创建对象”相同。创建对象时,将创建类的“实例”,因此将“实例化”一个类。


new运算符只需要一个后缀参数:一个构造器的调用。构造器的名称提供了要实例化的类的名称。
new运算符返回它创建对象的引用。此引用通常赋值给适当类型的变量,例如:

  1. Point originOne = new Point(23, 94);

由new运算符返回的引用不必分配给变量。也可以直接在表达式中使用。例如:

  1. int height = new Rectangle().height;

该声明将在下一节中讨论。

初始化对象

这是Point类的代码:

  1. public class Point {
  2. public int x = 0;
  3. public int y = 0;
  4. //constructor
  5. public Point(int a, int b) {
  6. x = a;
  7. y = b;
  8. }
  9. }

此类包含一个构造器。您可以识别构造器,因为其声明使用与类相同的名称,并且没有返回类型。Point类中的构造器采用两个整型参数,如代码(int a,int b)所声明的。以下语句提供23和94作为这些参数的值:

  1. Point originOne = new Point(23, 94);

下图说明了执行此语句的结果:
创建对象 - 图2
这是Rectangle类的代码,其中包含四个构造器:

  1. public class Rectangle {
  2. public int width = 0;
  3. public int height = 0;
  4. public Point origin;
  5. // four constructors
  6. public Rectangle() {
  7. origin = new Point(0, 0);
  8. }
  9. public Rectangle(Point p) {
  10. origin = p;
  11. }
  12. public Rectangle(int w, int h) {
  13. origin = new Point(0, 0);
  14. width = w;
  15. height = h;
  16. }
  17. public Rectangle(Point p, int w, int h) {
  18. origin = p;
  19. width = w;
  20. height = h;
  21. }
  22. // a method for moving the rectangle
  23. public void move(int x, int y) {
  24. origin.x = x;
  25. origin.y = y;
  26. }
  27. // a method for computing the area of the rectangle
  28. public int getArea() {
  29. return width * height;
  30. }
  31. }

每个构造器都可以使用基本类型和引用类型为矩形的原点,宽度和高度提供初始值。如果一个类具有多个构造器,则它们必须具有不同的签名。Java编译器根据参数的数量和类型来区分构造器。当Java编译器遇到以下代码时,它知道在Rectangle类中调用构造器,该构造器需要一个Point参数,后跟两个整型参数:

  1. Rectangle rectOne = new Rectangle(originOne, 100, 200);

这将调用Rectangle的构造器之一将origin初始化为originOne。同样,构造器设置width为100和height为200。现在有两个对同一个Point对象的引用-一个对象可以对其具有多个引用,如下图所示:
创建对象 - 图3
下面的代码调用Rectangle构造器,该构造器需要两个整型参数,这些参数提供width和height的初始值。如果检查构造器中的代码,您将看到它创建了一个新的Point对象,其x和y值初始化为0:

  1. Rectangle rectTwo = new Rectangle(50, 100);

以下语句中使用的Rectangle构造器不接受任何参数,因此称为无参数构造器

  1. Rectangle rect = new Rectangle();

所有类都有至少一个构造器。如果一个类没有显式声明任何构造器,则Java编译器会自动提供一个无参数的构造器,称为默认构造器。此默认构造器调用父类的无参数构造器,如果该类没有其他父级,则调用Object的构造器。如果父级没有构造器(Object确实有一个构造器),则编译器将拒绝该程序。