2 回答

TA贡献1816条经验 获得超6个赞
Java 语言不允许您像 C 和 C++ 那样在代码中区分堆/堆栈。
相反,它将所有数据类型分为两组:
基本类型:
这些是简单的内置数字类型,例如int
,double
或boolean
(不是 Java 中的数字类型)。
注意String
不是这样的类型!对象类型:
如果是类,那么它就是对象类型。这适用于内置类型(例如)String
和用户定义类型(例如您的Stream
类)。
对于这些类型,您看到的只是引用,无论您查看的是局部变量、类成员、实例成员还是函数参数。
让我们看一个简单的例子:
public class A {
public int a;
public static void main(String [] args) {
A var1 = new A();
A var2 = var1;
var1.a = 42;
System.out.println("var2.a = " + var2.a);
}
}
如果编译并运行这个示例,它将打印 42。
在 C++ 中,该行将A var2 = var1;
调用复制构造函数并创建一个新对象,但在 Java 中没有这样的事情。如果你想要一个副本,你需要clone
显式调用方法。
保存var1
和复制的内容var2
只是一个参考。所以两个变量“指向”同一个对象。
再说一遍——课程是否琐碎并不重要。即使一个类完全是空的,您仍然只能获得并使用对该类的任何对象的引用。
至于前面提到的基本类型,Java 有诸如Integer
和Boolean
for 它们的包装类。您可能想阅读有关“装箱”和“拆箱”的内容。
还要注意的另一件事是,某些类型是不可变的 - 也就是说,它们不提供在创建后更改数据的方法。
String
在Java中是一种不可变类型,但它也与任何其他类型有所不同。
它有特殊的特权。
虽然 Java 不像 C++ 那样支持运算符重载,但对于String
类型,该语言确实提供了一种特殊的方法+ operator
来执行字符串连接。
然而,由于String
对象是不可变的,任何串联操作都会创建一个全新的String
对象,甚至是这样的:
String a = "Hello"; a = a + " world!";
这将创建一个新字符串“Hello world”并将对其的引用存储在 中a
,而对旧“Hello”字符串的引用将在将来的某个时刻被垃圾收集。

TA贡献2011条经验 获得超2个赞
尽管在 Java 中一切都是按值传递的,但是原始数据类型(例如 int、char 和 boolean)与引用数据类型传递给方法的方式之间存在差异。当传递原始数据类型的值时,该值只能在特定方法的范围内更改。当传递引用数据类型的值时,引用将保持不变,但值将全局更改(或在对象初始化的任何范围内)。
添加回答
举报