“不要编写返回引用可变对象的访问器方法”

2018-08-06  本文已影响0人  暖熊熊

"注意不要编写返回引用可变对象的访问器方法".因为会破坏类的封装性,引用的内容可能会被改变,产生业务逻辑上的错误.
什么是可变对象?
先要搞清楚java中值传递和引用传递的问题,总结如下:
1.对象就是传引用
2.原始类型就是传值
3.String,Integer, Double等immutable类型因为没有提供自身修改的函数,每次操作都是新生成一个对象,所以要特殊对待。可以认为是传值。
Integer 和 String 一样。保存value的类变量是Final属性,无法被修改,只能被重新赋值/生成新的对象。 当Integer 做为方法参数传递进方法内时,对其的赋值都会导致 原Integer 的引用被 指向了方法内的栈地址,失去了对原类变量地址的指向。对赋值后的Integer对象做得任何操作,都不会影响原来对象。
所以,可变对象即immutable类型外的一般对象.[immutable类:如果类中的每个方法否不会改变其对象,这种类就是不可变的类.]
如果需要返回一个可变对象的引用,首先对它克隆,使用.clone,如return hireDay.clone();,会生成另一个内存位置上的对象副本.
很多人对"java程序设计语言总是采用按值调用"这句话与引用传递产生误会,认为矛盾,其实不矛盾,引用传递时,方法调用的是对象的拷贝值,也是对类对象的引用,当方法调用结束时,拷贝值不再使用,方法执行过程中通过拷贝值修改的对象值被改变.

package com.ghw.test;

import java.util.Date;

/**
 * java core中提到不要编写返回引用对象的访问器方法,此处对此演示
 * 这里user.getTime返回的是time这个Date对象的引用,因此d调用setTime
 * 修改的就是time这个对象。
 */
public class ReturnValueTest {
    public static void main(String[] args) {
        User user = new User();
        Date d = user.getTime();
        System.out.println(d);                  //Fri Aug 03 17:51:50 CST 2018
        d.setTime(1);
        System.out.println(user.getTime());     //Thu Jan 01 08:00:00 CST 1970
    }
}

class User {
    private Date time = new Date();

    public Date getTime() {
        return time;           //可以在这里添加clone,return (Date) time.clone();
    }
}
package com.ghw.test;

/**
 * java core中提到类中的方法可以访问所属类的私有特性(属性或方法)
 */
public class ReturnValueTest {
    public static void main(String[] args) {
        User user1 = new User();
        user1.hello();
    }
}

class User {

    public void hello() {
        helloa();
    }

    private void helloa() {
        System.out.println("helloa");
    }
}
上一篇 下一篇

猜你喜欢

热点阅读