你好,阿米戈!我想向你介绍变量的内部结构。如你所知,每个变量都与存储其值的内存区域关联。

“是的。你上次告诉过我。”

“太好了。你能记住真是不错。那我继续。”

“所有复合类型都由较简单的类型组成。而较简单的类型又由更简单的类型组成。直到最后,我们得到无法进一步简化的原始类型。因此称之为 – 原始类型。例如,int 是原始类型,但 String 是将数据以字符表方式存储的复合类型(其中每个字符是原始类型 char)。”

“非常有趣。继续。”

“复合类型是通过对简单类型进行分组而形成的。我们将这种类型称为。当我们在程序中定义一个新类时,我们声明一个新的复合数据类型。其数据要么是其他复合类型,要么是原始类型。”

Java 语言代码 说明
public class Person
{
   String name;
   int age;
}
声明一个新的复合类型 – Person
其数据存储在 String(复合类型)变量 nameint(原始类型) 变量 age
public class Rectangle
{
   int x, y, width, height;
}
声明一个新的复合类型 – Rectangle
它由四个 int(原始类型)变量组成。
public class Cat
{
   Person owner;
   Rectangle territory;
   int age;
   String name;
}
声明一个新的复合类型 – Cat。它具有以下变量:
owner,复合类型 Person
territory,复合类型 Rectangle
age,原始类型 int
name,复合类型 String

“到目前为止,一切都很清楚,但看起来可能有点奇怪。”

“大(复合)类型包含许多小(原始)类型。这正是这些类型的对象占用大量内存的原因 - 超出原始类型的变量。有时甚至更多。使用此类变量执行赋值操作通常会花很长时间,并且需要复制大部分内存。这就是复合类型的变量不存储对象本身,而只存储对象引用(即对象的四字节地址)的原因。这样做足以处理此类对象中的数据。Java 机器处理所有相关的复杂性。”

“我完全不明白。”

“我们以前说过,一个变量就像一个盒子。如果你想在盒子中存储数字 13,你可以在一张纸上写下 13 并将其放入盒子中。”

“但是想象一下,你需要在盒子(变量)中存储更大的东西。例如,狗、汽车或你的邻居。不要尝试将不可推动的物体推入盒子,你可以做得更轻松:用狗的照片代替实际的狗,用车牌代替真实的汽车,或者用邻居的电话号码代替邻居。”

“我们拿一张纸,写下邻居的电话号码。这就像对象的引用。如果我们复制写有邻居电话号码的纸并将其放入几个盒子,则现在有更多对你邻居的引用。但是,像以前一样,你仍然只有一个邻居。这样说没错,对吧?”

“以这种方式存储数据的一个重要特性就是你可以拥有对一个对象的多个引用

“太有趣了!我基本上明白了。请再告诉我一次 – 如果将一个复合类型的变量赋给相同复合类型的另一个变量会发生什么?”

“那样的话,这两个变量将存储相同的地址。这意味着,如果更改一个变量所引用的对象的数据,则会更改其他变量所引用的数据。两个变量引用同一个对象。当然,可能还有许多其他变量也存储该对象的引用。”

“如果复合(引用/类)类型的变量不包含对某个对象的引用,它们将做什么?有这种可能吗?”

“是的,阿米戈。你已经超前提问了。这是可能的。如果引用(复合)类型的变量未存储某个对象的引用,它将存储所谓的‘null 引用’。大致说来,这意味着它引用地址为 0 的对象。但是,Java 机器从不使用此地址创建对象,因此它始终知道,如果引用变量包含 0,则它不指向任何对象。”

Java 语言代码 说明
String s;
String s = null;
等效语句。
Person person;
person = new Person();
person = null;
我们创建值为 null 的 person 变量。
我们将新创建的 Person 对象的地址赋给该变量。
我们将 null 赋给该变量。
Cat cat = new Cat();
cat.owner = new Person();
cat.owner.name = "God";
我们创建 Cat 对象,并将其地址存储在变量 cat 中;cat.owner 等于 null。
我们将 cat.owner 设置为等于新创建的 Person 对象的地址。
cat.owner.name 仍然等于 null。
我们将 cat.owner.name 设置为等于“上帝”

“我的理解正确吗?变量分为两种类型:原始类型和引用类型。原始类型直接存储值,而引用类型存储对象的引用。原始类型包括 int、char、boolean 和许多其他类型。引用类型包括其他所有类型。我们使用类来创建它们。”

“你说的完全正确,小伙子。”

“嗯,你说你已经完全明白了。这里有一些任务,可以帮助你增强对知识的理解。”

1
任务
Java 语法,  第 2 级课程 2
已锁定
计算圆的周长
我们有一个计划。现在来实现它。首先,实现一种计算圆周长的方法。要完成此任务,你需要在方法中写入正确的公式并指定参数。但是 pi 呢?我们知道它是 3.141592... 直至无穷。我们把问题简化一下:让 pi = 3.14。
7
任务
Java 语法,  第 2 级课程 2
已锁定
我们的第一个转换器!
你可能已经多次使用电子转换器或程序将一个单位的数量转换为另一个单位的数量。例如,将美元转换为英镑,或者将公里转换为英里。现在,我们来编写这样一个工具。具体来说,我们将编写一个将摄氏度转换为华氏度的程序。
3
任务
Java 语法,  第 2 级课程 2
已锁定
Person(人)来自哪里?
在 Java 中,人与其他类来自同一个地方:来自程序员的大脑。作为类的创建者,对于什么对类重要,什么对类不重要要深思熟虑。如果这样做了,那么类才是有意义并且有用的。咱们开始吧。我们来创建一个 Person 类,该类允许我们的 Person 拥有名字、年龄、体重和... 金钱。接下来我们将创建一个对象。
3
任务
Java 语法,  第 2 级课程 2
已锁定
家庭关系
程序员可以通过几次灵巧的手指动作来创建一个男人和一个女人。轻松自在:我们将编写适当的类并创建对象。我们来处理一对已婚夫妇:我们将创建 Man 和 Woman 对象,然后将对 Woman 的引用保存在 man.wife 中,并将对 Man 的引用保存在 woman.husband 中。看到了吗?你甚至不需要结婚证。
3
任务
Java 语法,  第 2 级课程 2
已锁定
加薪
当程序员是有好处的:你的薪水增长会非常快。如果没什么增长,你的黑客朋友帮一点小忙就行。假设您可以访问自动工资系统。你需要编写一个 interceptor 方法,在每次发薪水时增加 1000 美元。
1
任务
Java 语法,  第 2 级课程 2
已锁定
计算器的一部分
让计算机为我们计数!这是创建它们的最终目的。在此任务中,我们要求计算机计算两个数的总和及乘积。一切都非常简单:我们声明几个 int 变量,为它们赋值,将其相加和相乘,然后显示结果。