Java形参对象的一些坑,超出你想象

58 篇文章 0 订阅

1. Java形参对象的一些坑

先来看问题:

	public void wantChangeObj2(UserInfo user) {
		 user.setUserName("change");  //会影响原为的对象(实参对象)
		 user=null;  //改了,会对实参有影响吗?
   }

为什么?

方法内修改会影响原始的对象(也就是实参对象),因为它修改了对象的状态。

但引用却不能修改,对象引用是按值传递的。

例子:

//Java形参对象的一些坑
public class TestObject2 {
	
	public static void main(String[] args) {
		TestObject2 test=new TestObject2();
		
		UserInfo user=new UserInfo();
		user.setUserPassWord("abc");
		user.setUserName("change00");
		test.wantChangeObj2(user);
		
		System.out.println(user.getUserName());
		System.out.println(user.getUserPassWord());
	}
	//分析输出结果,并解释为什么?
	//change
	//abc

//	 这是因为在方法wantChangeObj2中,虽然修改了user对象的userName属性,但在方法末尾将user对象赋值为null。
//	 这不会影响原始的user对象,因为Java中的参数传递是按值传递的,即传递的是对象的引用的副本。在方法内部修改引用本身并不会影响原始的引用。
//	所以尽管在方法中将user赋值为null,但原始的user对象仍然存在,且其属性值没有改变。
	public void wantChangeObj2(UserInfo user) {
//		System.out.println(user.getUserName());
		 user.setUserName("change");  //会影响原为的对象(实参对象)
//		 System.out.println(user.getUserName());
		 user=null;  //改了,会对实参有影响吗?
		 //为什么第一句有效,第二句无效?
//		 System.out.println(user.getUserName());
		 
//		 在方法wantChangeObj2中,user.setUserName("change");会影响原始的对象(也就是实参对象),因为它修改了对象的状态。
//		 而user=null;这行代码不会影响原始的对象。这是因为它只会将方法内部的user引用指向null,但不会影响传递给方法的原始对象。在Java中,
//		 对象引用是按值传递的,所以当你将user设置为null时,只是改变了方法内部的引用,而原始对象仍然存在。
	}
	
//	方法内传入的对象形参的生命周期?
//	方法内传入的对象形参的生命周期与方法的执行时间相同。当调用方法时,会将对象的引用传递给方法的形参,形参将在方法执行期间引用相同的对象。
//	一旦方法执行结束,形参的生命周期也随之结束,形参不再存在,但实参对象仍然存在于内存中,直到没有任何引用指向它时,才会被垃圾回收器回收。
//	需要注意的是,如果在方法内部修改了对象的状态,这些修改会影响到实参对象,因为实参和形参引用的是同一个对象。但是,即使形参被设置为null,
//	实参对象仍然存在,因为形参的生命周期结束并不会影响实参对象的生命周期。
	
	
//	“即使形参被设置为null,实参对象仍然存在”,
//	那在方法内,是否有必要将形参对象设置为null呢?
//	user=null;
	
//	在大多数情况下,在方法内将形参对象设置为null并不是必要的。这是因为在方法结束时,形参的生命周期就会结束,而实参对象并不受影响,它仍然存在于内存中,直到没有任何引用指向它时才会被垃圾回收器回收。
//	通常情况下,只有在需要显式地告知垃圾回收器某个对象可以被回收时,才需要将引用设置为null。这种情况通常发生在对象的作用域结束后,但是你希望尽快释放对象占用的内存空间时。在大多数情况下,Java的垃圾回收器会在适当的时候自动回收不再使用的对象,因此不需要手动将形参对象设置为null。
//	总的来说,除非有特殊的内存管理需求,否则通常不需要在方法内将形参对象设置为null。
}

2. Java final形参对象的一些坑

先来看问题:

	public void wantChangeObj2(final UserInfo user) {
//		 user=null;//是否允许
//是否允许修改user的属性值?
//user=new UserInfo(); //是否允许给对象重新赋值??
	}

为什么?

在例子中,使用final修饰方法参数user,表示在方法内部无法修改user对象的引用,

// 但是仍然可以修改user对象的属性值。

例子:

package com.test.testobj;

//Java final形参对象的一些坑
public class TestObject {
	
	public static void main(String[] args) {
		TestObject test=new TestObject();
		
		UserInfo user=new UserInfo();
		user.setUserPassWord("abc");
		user.setUserName("change00");
		UserInfo user0= test.wantChangeObj(user);
		
		System.out.println(user.getUserName());
		System.out.println(user.getUserPassWord());
		
		System.out.println(user0.getUserName());
		System.out.println(user0.getUserPassWord());
		
		
	}
	

	
//	public void wantChangeObj(final UserInfo user) {//还是会改变对象user
	public UserInfo wantChangeObj(final UserInfo user) {//还是会改变对象user
		
		user.setUserName("change");
//		在例子中,使用final修饰方法参数user,表示在方法内部无法修改user对象的引用,
//		但是仍然可以修改user对象的属性值。如果想要完全限制在方法内部改变对象,可以使用不可变对象或者深拷贝的方式来实现。
		
		UserInfo user2=new UserInfo();
		 return user2; //返回一个新的,还是可以的.
//		 user=new UserInfo(); //不允许
		 
//		 user=null;//不允许
//		return user;
	}
	
	public void wantChangeObj2(final UserInfo user) {
//		 user=null;//不允许
		
	}
}

 

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值