java中如何通过修改参数的值,从而修改原函数的值
在c语言中有指针和地址的定义,而在java中没有那么明确,但是其实本质上一样的,想要搞懂引用就必须大概了解变量是如何被存储的。
首先,基本数据类型是直接保存的,而引用类型变量是保存的变量的存储的值而非直接保存数据。
例如
public void main(String[] args){
int num = 10;
String str = "hello";
test(str,num);
}
public void test(String str,int num){
//引用类型, 但是String是不允许被修改的,修改会重新开辟内存空间,不会改变原来的值
str = "hello world";
//基本数据类型,重新开辟新的空间函数执行完毕会被当作垃圾回收,不会改变
num = 11;
}
那么其实了解过前端ES6语法中国对于const的定义的同学都知道,const类型会现在对地址的修改,而不限制该地址指向内容的修改。所以只要不改变地址的化,原始值就对应的被修改。
例如
public void main(String[] args){
StringBuffer sb = new StringBuffer("hello");
test1(sb);
test2(sb);
}
public void test1(StringBuffer sb){
sb.append("world"); //引用类型,且没有修改内存地址,main函数sb的值会改变
}
public void test2(StringBuffer sb){
sb = new StringBuffer("hello world"); //虽然是引用类型但是地址改变, main中sb不改变
}
那么只要抓住这点就能理解其他所有的类型了 我在举一个数组的例子
public static void main(String[] args) {
int nums[] = {1,1};
func1(nums);
func2(nums);
for(int t:nums)
System.out.println(t);
}
//原始值会被改变
public static void func1(int nums[]) {
nums[1] = 2;
}
public static void func2(int nums[]) {
nums = new int[2]; //地址改变,初始值不受影响
nums[0] =1;
nums[1] = 2;
}
其他的像List,Deque,Set等都是如此,只要不做影响地址的操作都是可以改变初始值的。
补充
面试中也常考:JAVA中提供了四种引用类型:强引用、软引用、软引用和虚引用。
在四种引用类型中,只有强引用FinalReference类型变量是包内可见的private,其他三种引用类型均为public,可以在程序中直接使用。
强引用
引用最多的就是强引用。强引用不会被Jvm垃圾回收机制回收。
例如:StringBuilder sb = new StringBuilder(“hello word”); sb指向堆空间,可以用sb直接访问目标对象,同时不会被强制回收就会导致内存泄露。
软引用
用软引用要用java.lang.ref.SoftReference包,JVM会根据当前堆的使用情况来判断何时回收。当堆使用率临近阈值时,软引用对象会被回收。被回收后在调用该对象会返回null
弱引用
只要被Jvm的垃圾回收发现就会被回收,不管内存的使用状况
虚引用
强度最小,随时被垃圾回收机制回收,调用get()方法永远为空。