📜  Java中的new运算符

📅  最后修改于: 2020-03-24 04:54:13             🧑  作者: Mango

当您在Java中声明一个类时,您只是在创建一个新的数据类型。一个类提供了对象的蓝图,您可以从类创建对象。但是,获取类的对象需要两个步骤:

    1. 声明:首先,必须声明一个类类型的变量。此变量未定义对象。相反,它只是可以引用对象的变量。以下是声明的一般语法,并带有示例:
      语法:
      class-name var-name;
      范例:
      //声明对Box类的对象的引用
      Box mybox;

      处于这种状态的变量当前不引用任何对象,可以如下所示(变量名mybox,加上指向无内容的引用):

    2. 实例化和初始化:其次,您必须获取对象的实际物理副本并将其分配给该变量。您可以使用new运算符执行此操作。该new运算符通过动态地分配(即,在运行时分配)存储器,作用于一个新的对象并返回该存储器中的实例的类的引用。然后,此引用存储在变量中。因此,在Java中,必须动态分配所有类对象。new运算符之后还调用了一个类构造函数,该构造函数初始化了新对象。构造函数定义创建的类的对象时,会发生什么。构造函数是所有类的重要组成部分,并具有许多重要属性。在下面的示例中,我们将使用默认构造函数。以下是实例化和初始化的一般语法,并带有示例:
      语法:
      var-name = new class-name();
      示例:
      //通过new运算符
      //和Box类的默认构造函数进行初始化
      mybox = new Box();

      在理解之前,new是如何动态分配内存的,让我们看一下Box类的原型。

      class Box
      {
          double width;
          double height;
          double depth;
      }

      第二步之后的变量(当前引用一个类对象)可以如下所示(变量名mybox,再加上指向Box对象的引用):

因此,类变量的声明、类的实例化和类的对象的初始化的说明如下图:



重要事项:

  1. 以上两个语句可以重写为一个语句。
    Box mybox = new Box();
  2. new运算符返回的引用不必分配给类变量。也可以直接在表达式中使用。例如:
    double height = new Box().height;
  3. 由于数组是Java中的对象,因此在实例化数组时,我们使用new运算符。例如:
    int arr[] = new int[5];
  4. 在这一点上,您可能想知道为什么对于原始数据类型不需要使用new运算符。答案是Java的原始类型未实现为对象。相反,它们被实现为“普通”变量。这样做是为了提高效率。
  5. 短语“实例化一个类”的含义与“创建对象”相同。创建对象时,将创建类的“实例”,因此将“实例化”一个类。

 

分配对象引用变量

当您将一个对象引用变量分配给另一对象引用变量时,您不是在创建对象的副本,而只是在创建引用的副本。让我们通过一个例子来理解这一点。

// Java 分配对象引用变量
// Box 类
class Box
{
    double width;
    double height;
    double depth;
}
// 测试代码
public class Test
{
    
    public static void main(String[] args)
    {
        // 创建box对象
        Box b1 = new Box();
        // 把b2分配给b1
        Box b2 = b1;
        // b1和b2的height
        System.out.println(b1.height);
        System.out.println(b2.height);
        // 通过b2改变height
        b2.height = 20;

        // b2的height调整之后
        System.out.println(b1.height);
        System.out.println(b2.height);
    }
}

输出:

0.0
0.0
20.0
20.0

说明:首先,让我们了解以下代码片段在上述程序中的作用。

Box b1 = new Box();
Box b2 = b1;

您可能会认为b2被分配了对b1所引用对象副本。也就是说,您可能会认为b1b2指的是单独且不同的对象。但是,这是错误的。相反,在执行该片段之后,b1b2都将引用同一对象。因此,通过b2对对象所做的任何更改都会影响b1所针对的对象是指,因为它们是同一对象。当我们通过b2改变box的height时,也可以通过输出来验证。
这种情况可以说明如下:


注意:尽管b1b2都引用相同的对象,但是它们没有以任何其他方式链接。例如,随后对b1的赋值将简单地 b1与原始对象脱钩而不影响该对象或不影响b2。例如:

Box b1 = new Box();
Box b2 = b1;
// ...
b1 = null;

此处,b1已设置为null,但b2仍指向原始对象。

将对象引用变量传递给方法

当我们将对象引用传递给方法时,接收该方法的参数将引用与参数所引用相同的对象。