Java值传递小结

本文详细探讨了Java中方法参数的传递方式,包括基本数据类型和引用类型的区别,并通过具体示例展示了不同类型的参数如何影响方法内外的对象状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


JAVA 中方法参数分为两大类:基本数据类型,引用对象。


方法在传递参数时都是采用值传递,不过对于基本数据类型传递的是数据的字面值,如(int a = 2;)此处传递的值为2;对于对象引用,传递则是引用地址指向。具体示例见如下代码:

public class Mill {

	double num = 55.5D;
	String str = new String("good");
	char[] ch = {'a','b','c'};
	boolean flag = true;
	float f = 35.5f;
	
	public static void main(String[] args) {
		Mill ex = new Mill();
		change(ex.str, ex.ch, ex, ex.f);
		System.out.println(ex.string);
		System.out.println(ex.ch);
		System.out.println(ex.num);
		System.out.println(ex.flag);
		System.out.println(ex.f);
		
	}
	
	public static void change(String str,char[] ch,Mill mill,float f ) {
		mill.num = 10.1D;
		str = "test ok";
		ch[0] = 'g';
		mill = new Mill();
		f = 44.5f;
		mill.flag = false;
	}
}

【输出结果】: 

good
gbc
10.1
true
35.5

结合以上案例进行实际分析:

上面

change(String str,char[] ch,Mill mill,float f )
方法中String类型比较特殊,放在最后说。

char[] 字符数组和Mill为引用对象,float为基本类型。

mill.num = 10.1D;

通过上图,可以看出ex对象在进入change方法时,将自己的引用地址传递给了mill变量,所以此时两者指向的是同一个对象,所以在mill.num = 10.1D处改变了引用对象的成员属性num,所以在输出时候,ex.num的值也改变了。char[]数组ch虽然是mill的一个成员属性,但它也是引用地址传递,所以也是如此,不再解释。

f = 44.5f;

由于ex.f是float类型的,在经过方法时,传递的是它的字面值,此时,在栈内存中开辟了一块新的区域用来存放float变量f,所以在方法中操作f对ex.f的值没有任何影响,而在方法结束时,f的作用域结束,在随后一段时间内,会被jvm的垃圾回收器回收。

mill = new Mill();
mill.flag = false;

当mill进入change方法时,和ex指向的是同一个对象实例1,运行mill = new Mill();后,产生一个新的对象实例2,mill 此时指向实例2,然后mill.flag = false;改变的是实例2的属性,与实例1无关。

str = "test ok";
String虽然也是引用类型,但它比较特殊,这还涉及到String的字符串池,此处进行简单解释:


String类在内存中单独管理一个字符串池,它的创建机制是这样的:当创建一个新的字符串的时候,它会先从字符串池中查找是否有这个字符串,如果存在就讲声明变量指向这个字符串所在的地址,没有才去新建一个字符串维护在变量池中,字符串池中的字符串不会被修改。

开始时候,str 指向“good”字符串,进入change方法后,拷贝一个新的引用地址给change中str变量,然后运行str = “test ok”,他会发现没有这个字符串,然后就去新建了一个字符串“test ok”,此时,change中str变量指向“test ok”(此处改变了引用地址,而不是改变原有地址对应的内容),原有的地址依然是字符串“good”,所以在main中的ex.str指向的地址处内容并没有改变,还是“good”。


Java多线程是指在一个Java程序中同时执行多个线程,每个线程都是独立的执行流。Java中创建线程的方式有三种:继承Thread类、实现Runnable接口和实现Callable接口。每种方式都有其优缺点。 1. 继承Thread类创建线程类: ```java class MyThread extends Thread { public void run() { // 线程执行的代码 } } // 创建线程对象并启动线程 MyThread thread = new MyThread(); thread.start(); ``` 优点:简单易用,可以直接重写Thread类的run()方法。 缺点:由于Java不支持多继承,继承了Thread类就无法再继承其他类。 2. 实现Runnable接口创建线程类: ```java class MyRunnable implements Runnable { public void run() { // 线程执行的代码 } } // 创建线程对象并启动线程 Thread thread = new Thread(new MyRunnable()); thread.start(); ``` 优点:避免了单继承的限制,可以继续继承其他类或实现其他接口。 缺点:需要额外创建Thread对象,并将Runnable对象作为参数传递给Thread对象。 3. 实现Callable接口创建线程类: ```java class MyCallable implements Callable<Integer> { public Integer call() throws Exception { // 线程执行的代码 return 0; } } // 创建线程池对象 ExecutorService executor = Executors.newFixedThreadPool(1); // 提交Callable任务并获取Future对象 Future<Integer> future = executor.submit(new MyCallable()); // 获取线程执行结果 int result = future.get(); ``` 优点:可以获取线程执行的结果,并且可以抛出异常。 缺点:相对于前两种方式,使用Callable需要更多的代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值