运行完一个Findbugs时,发现它报了一个警告: CccFans.getRowCreateTime() may expose internal representation by returning CcFans.rowCreateTime()以及CcFans.setRowCreateTime(Timestamp) may expose internal representation by storing an externally mutable object into CcFans.rowCreateTime

原因

用例子来说明:

package org.se;

public class Main {
	public static void main(String[] args) {
		Person p = new Person();
		p.setName("hello");
		PersonHolder ph = new PersonHolder();
		ph.setP(p);
		System.out.println(ph.getP().getName());
		p.setName("new Hello");
		System.out.println(ph.getP().getName());
	}

	public static class PersonHolder {
		private Person p;

		public Person getP() {
			return p;
		}

		public void setP(Person p) {
			this.p = p;
		}
	}

	public static class Person {
		private String name;

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

	}
}

打印的结果:
hello
new Hello

这里,已经在ph.setP()后,但p后面又修改了自己的数据(p.setName(“new Hello”),这样子,下次ph使用时,就是新的数据了,而不是使用setP()时的p`的状态时的数据. 这只是警告,存在可能的隐患。

建议

凡是set一个对象的时候,都应该建议set对象的副本。比如,改进后这样子:

package org.se;

public class Main {
	public static void main(String[] args) throws CloneNotSupportedException {
		Person p = new Person();
		p.setName("hello");
		PersonHolder ph = new PersonHolder();
		ph.setP(p);
		System.out.println(ph.getP().getName());
		p.setName("new Hello");
		System.out.println(ph.getP().getName());
	}

	public static class PersonHolder {
		private Person p;

		public Person getP() {
			return p;
		}

		public void setP(Person p) throws CloneNotSupportedException {
			this.p = (Person) p.clone();
		}
	}

	public static class Person implements Cloneable {
		private String name;

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		protected Object clone() throws CloneNotSupportedException {
			Person p = new Person();
			p.name = this.name;
			return p;
		}

	}
}

打印的结果为:
hello
hello