17. 请解释 Java 中的值传递和引用传递。
在Java编程语言中,参数传递可以分为两种类型:值传递(pass by value)和引用传递(pass by reference)。不过,值得注意的是,Java在方法调用时始终是进行值传递,这个概念经常引起误解,特别是在涉及对象时。
值传递(Pass by Value):
- 值传递是指在方法调用时,实际参数的值被复制到一个局部变量(即形式参数)中。
- 如果参数是基本数据类型(如int、float、double等),那么这个值的副本就是基本数据类型值本身。
- 如果参数是对象,那么复制的值是对象的引用,而不是对象本身。因此,这里所说的“值”实际上是指对象的引用值。
示例(基本数据类型):
public void swap(int a, int b) { int temp = a; a = b; b = temp; }
在上面的代码中,尽管在
swap
方法内部交换了a和b的值,但原始调用处的值并未改变,因为传递的只是基本数据类型值的副本。引用传递(Pass by Reference):
- 引用传递是指方法接收的是实际参数的引用,也就是说,形式参数和实际参数指向内存中的同一个对象。
- Java并不支持真正意义上的引用传递,但是当我们传递对象时,由于传递的是对象的引用值,有些人可能会错误地称之为引用传递。
- 当我们在方法内部改变引用指向的对象时,外部的实际参数也会受到影响,因为它们指向的是同一个对象。
示例(对象):
public class MyObject { public int value; } public void changeObject(MyObject obj) { obj.value = 10; }
在这个例子中,如果我们在外部创建了一个
MyObject
对象,并将其传递给changeObject
方法,那么在changeObject
内部对obj.value
的任何修改都会影响到原始对象,因为它们共享相同的引用。
总结来说,Java中的参数传递可以看作是这样的:
- 基本数据类型:传递数据值本身。
- 对象:传递对象的引用值,而非对象本身。
了解这一点对于理解在方法调用时数据如何被操作是非常重要的。
18. Java 中的 final 关键字有哪些用途?
Java 中的 final
关键字主要用于表示某个元素不能被改变。以下是 final
关键字的主要用途:
声明常量:当用于基本数据类型时,
final
可以保证该变量的值一旦被初始化之后就不能被改变。对于引用类型,final
保证引用本身不会改变,但是引用指向的对象内容可以改变。final int MAX_VALUE = 100; final List<String> names = new ArrayList<>(); // names 引用不能指向新的对象,但可以向 names 添加或删除元素
防止方法被覆盖:如果某个方法被声明为
final
,则任何继承这个类的子类都不能覆盖这个方法。public class ParentClass { public final void finalMethod() { // ... } } public class ChildClass extends ParentClass { // 不能覆盖 finalMethod() }
防止类被继承:如果一个类被声明为
final
,则它不能被其他类继承。public final class FinalClass { // ... } // 无法继承 FinalClass // public class NewClass extends FinalClass {}
参数的 final 用法:当使用
final
参数时,表示在方法内部不能改变参数的值。public void someMethod(final int number) { // number = 10; // 编译错误,不能改变 final 参数的值 }
局部变量的 final 用法:当局部变量被声明为
final
时,一旦被赋值之后就不能再改变。public void someMethod() { final int localVariable = 10; // localVariable = 20; // 编译错误,不能改变 final 局部变量的值 }
匿名内部类:当匿名内部类使用外部局部变量时,该变量需要是
final
的。这是因为局部变量生命周期比匿名内部类短,为了保证内部类中使用变量的安全,需要它是常量。public void someMethod() { final int number = 10; Runnable runnable = new Runnable() { public void run() { System.out.println(number); } }; }
以上就是 final
关键字在 Java 中的主要用途。使用 final
可以增强代码的安全性,确保某些元素不被改变,有助于避免并发问题,并且可以帮助编译器优化代码。