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;//不允许
}
}