使用getter和setter(只获取和设置)而不是简单地为这些变量使用公共字段有什么好处?

如果getter和setter所做的不仅仅是简单的get/set,我可以很快地解决这个问题,但我不是100%清楚如何做到:

public String foo;

比:

private String foo;
public void setFoo(String foo) { this.foo = foo; }
public String getFoo() { return foo; }

而前者需要的样板代码要少得多。


当前回答

考虑使用访问器是有充分理由的,因为没有属性继承。请参见下一个示例:

public class TestPropertyOverride {
    public static class A {
        public int i = 0;

        public void add() {
            i++;
        }

        public int getI() {
            return i;
        }
    }

    public static class B extends A {
        public int i = 2;

        @Override
        public void add() {
            i = i + 2;
        }

        @Override
        public int getI() {
            return i;
        }
    }

    public static void main(String[] args) {
        A a = new B();
        System.out.println(a.i);
        a.add();
        System.out.println(a.i);
        System.out.println(a.getI());
    }
}

输出:

0
0
4

其他回答

我能想到一个原因,为什么你不希望一切都公开。

例如,您从未打算在类外部使用的变量可以被访问,甚至可以通过链变量访问(即object.item.origin.x)直接访问。

通过将所有内容都设为私有,并且仅将您想要扩展的内容以及可能在子类中引用的内容设为受保护的,并且通常只将静态最终对象设为公共,那么您就可以通过使用setter和getter访问您想要的程序内容来控制其他程序员和程序可以在API中使用什么,以及它可以访问什么,以及不能访问什么,或者可能是其他恰好使用您的代码的程序员,可以在您的程序中进行修改。

因为从现在起2周(月、年),当您意识到setter需要做的不仅仅是设置值时,您还将意识到该属性已直接用于238个其他类:-)

我花了很长时间来思考Java案例,我相信真正的原因是:

接口的代码,而不是实现接口只指定方法,不指定字段

换句话说,在接口中指定字段的唯一方法是提供一个用于写入新值的方法和一个用于读取当前值的方法。

这些方法是臭名昭著的getter和setter。。。。

很多人都在谈论二传手和二传手的优点,但我想扮演魔鬼代言人的角色。现在我正在调试一个非常大的程序,程序员们决定让所有的东西都变得更好和更好。这看起来不错,但这是一场逆向工程噩梦。

假设你正在查看数百行代码,你会发现:

person.name = "Joe";

这是一段非常简单的代码,直到你意识到它是一个setter。现在,您遵循该setter,发现它还设置了person.firstName、person.lastName、person.isHuman、person.hasReallyCommonFirstName,并调用person.update(),后者将查询发送到数据库等。哦,这就是发生内存泄漏的地方。

乍一看就理解一段本地代码是具有良好可读性的一个重要特性,getter和setter往往会打破这一特性。这就是为什么我尽量避免使用它们,并在使用它们时尽量减少它们所做的事情。

我知道现在有点晚了,但我想有些人对表演感兴趣。

我做了一个性能测试。我写了一个类“NumberHolder”,它包含一个整数。您可以使用getter方法读取该IntegeranInstance.getNumber()或通过使用anInstance.number直接访问数字。我的程序通过两种方式读取数字1000000000次。该过程重复五次,并打印时间。我得到了以下结果:

Time 1: 953ms, Time 2: 741ms
Time 1: 655ms, Time 2: 743ms
Time 1: 656ms, Time 2: 634ms
Time 1: 637ms, Time 2: 629ms
Time 1: 633ms, Time 2: 625ms

(时间1是直接方式,时间2是吸气方式)

你看,吸气器(几乎)总是快一点。然后我尝试了不同次数的循环。我用了1000万和10万,而不是100万。结果:

1000万次循环:

Time 1: 6382ms, Time 2: 6351ms
Time 1: 6363ms, Time 2: 6351ms
Time 1: 6350ms, Time 2: 6363ms
Time 1: 6353ms, Time 2: 6357ms
Time 1: 6348ms, Time 2: 6354ms

1000万次循环,时间几乎相同。以下是10万(10万)个循环:

Time 1: 77ms, Time 2: 73ms
Time 1: 94ms, Time 2: 65ms
Time 1: 67ms, Time 2: 63ms
Time 1: 65ms, Time 2: 65ms
Time 1: 66ms, Time 2: 63ms

同样,对于不同数量的循环,getter比常规方法快一点。我希望这对你有所帮助。