一、对象引用
Java不允许使用指针,取而代之的是对象引用。对象引用可理解为指向对象的指针,但无法像真实的指针一样指向内存的任意位置,也不能像操作地址那样操作对象引用。除基本类型外的所有类型均为对象,所有的对象又均为引用类型,对象引用是Java安全性的关键。
class Solution { public static void main(String[] args) { Object obj;//声明对象引用 obj = new Object();//实例化对象 } }
二、垃圾回收
Java的垃圾回收机制可以自动释放内存。当一个对象不再存在引用时,便认为该对象不再被需要,Java虚拟机会自动回收该对象占用的内存。不需要像C/C++那样显式释放内存。类似C++的析构函数,Java可通过重写对象的finalize方法来显示指明当对象被释放时进行何种操作。
class Solution { protected void finalize() { //finalization code } }
三、访问权限
访问权限 | 同类 | 同包 | 子类 | 不同包 |
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
default | √ | √ | × | × |
private | √ | × | × | × |
四、参数传递
class Solution { public static void change(String s) { s += " Java"; } public static void main(String[] args) { String s = "Hello"; change(s); System.out.println(s);//输出Hello而非Hello Java } }
String类型在发生变化时不会对原本的对象做出变化,而是再次实例化一个新的对象并改变引用。理论上修改引用类型会改变原本对象的值,但这样的结论对于String类型不适用。修改后的String引用会指向新的对象,而原本的对象并未发生改变。需要实现修改字符串的方法应当使用StringBuilder或StringBuffer。
五、可变长度参数
class Solution { public static int sum(int... nums) { int res = 0; for (int i : nums) res += i; return res; } public static void main(String[] args) { int a = sum(1, 2, 3, 4, 5); System.out.println(a); } }
当需要传递不确定数量的参数时,我们会选择将参数存入数组后以数组作为参数进行传递。但是将数组存入数组的步骤是繁琐的,我们希望直接将不确定数量的变量作为参数进行传递。可变长度参数事实上是一个隐式声明的数组。可变长度参数必须是最后一个参数并且只能存在一个可变长度参数,声明第二个可变长度参数是非法的。重载方法的参数也不允许出现歧义。