1

我正在阅读一本 java 书,其中说在访问/修改不同类中的变量时,应该使用 get/set 方法来操作它们。

我的问题是,加班和在大型项目中使用gets/sets 不会危及应用程序性能?

类似的问题,通常我们应该更喜欢使用数组来损害更抽象的数据类型(例如实例列表),因为数组通常对缓存更友好。

4

5 回答 5

5

除非您正在编写必须在某些嵌入式设备中运行的高效算法的关键部分,否则您的首要目标应该是生成简单、可读、可维护的代码。OOP 在这方面通过封装等特性帮助我们。Getter 和 setter 允许封装一些行为。它们也是多种 Java 技术(如 JSP EL、各种脚本语言、IDE 等)使用的标准。一般来说,性能不应该是主要的设计因素。

Java 即时编译器非常聪明,并且会内联对 getter 和 setter 的调用。

Java 集合等高级抽象也有助于编写更简单、更安全的代码,并且已经过测试和优化。用数组重新实现它们提供的所有东西会导致难以维护、效率低下的代码。绝对使用 Java 集合,并且比数组更喜欢它们。

请记住,与速度较慢的正确代码相比,有效的错误代码是无用的。

于 2012-11-03T12:56:30.230 回答
2

我的问题是,加班和在大型项目中使用gets/sets 不会危及应用程序性能?

没有。它促进了数据封装,是一种很好的 OO 实践。

软件对象在概念上类似于现实世界的对象:它们也由状态和相关行为组成。对象将其状态存储在字段(某些编程语言中的变量)中,并通过方法(某些编程语言中的函数)公开其行为。方法对对象的内部状态进行操作,并作为对象到对象通信的主要机制。隐藏内部状态并要求通过对象的方法执行所有交互被称为数据封装——面向对象编程的基本原则。

来自Java Trail

我们是否应该更喜欢使用数组来损害更抽象的数据类型(例如实例列表),因为数组通常对缓存更友好。

这取决于您的用例。
我认为缓存友好意味着内存效率更高。删除元素时会涉及一些碎片,并且数组设计具有一定的初始容量。它从ArrayList10 开始,然后根据您的需要不断调整大小。

但是,使用 Array 的好处是您可以按索引访问元素。

于 2012-11-03T12:59:32.950 回答
1

如果您正在构建一个数据对象,其唯一目的是获取和设置字段,那么 getter 和 setter 是一个好主意。它们允许您在必要时验证和同步,甚至可以在不破坏旧代码的情况下更改字段(只需更改字段并保持 API 不变)。

但是,在大多数情况下(如果不是所有其他情况),getter 和 setter 是一个主意。这个问题甚至与性能没有任何关系。问题在于,在上述数据对象之外,getter 和 setter 破坏封装的程度几乎与直接暴露底层变量本身一样严重。 如果必须有可见变量,则使用 get/set 方法;但是,在大多数情况下,您不必有可见的变量。

消费者不应该关心,或者在大多数情况下甚至不应该知道类包含的变量。这就是封装的本质——不是这种“将变量隐藏在 getter 后面”的误导概念,而是“隐藏变量,周期”。你绝对不应该设置它们;管理它的变量是类的责任,如果用户在使用它之前必须为它设置类的操作参数,那么类就坏了。如果调用者必须getAnything()在调用你的方法之后,那么方法签名是错误的;他们得到的东西应该是一个返回值

完全公开成员变量,无论是通过 getter/setter 还是仅仅通过公开该字段,只有当该字段是数据时才应考虑。其他所有情况都需要更好的封装。

至于数组与集合,这取决于具体情况。我个人喜欢在两者都有意义的情况下使用集合,但这是个人偏好。在决定这一点时,诸如缓存位置之类的事情不应该是您的主要关注点。但请记住,ArrayList在大多数情况下,an 与普通的旧数组一样对缓存友好。如果您定义要获取和返回List的内容,那么您可以随意切换 List 子类型,因为您发现特定的子类型现在更适合您的需求。只需尝试在不破坏现有代码的情况下将 API 的数组返回值切换为链表即可。:)

于 2012-11-03T13:49:39.823 回答
1

这个词是封装。使用getandset可以更容易地控制对变量的访问(例如,检查值是否在范围内、同步、控制它们何时被更改——对并发编程中的竞争条件很有用——、使用它们的线程是否有权这样做, ETC。)。特别是对于大型项目,这比微小的开销更重要。

此外,getandset也在 Java bean 的定义中,它们被许多框架(JPA、JSF 等)使用。

数组没问题,但是如果您不知道数组的确切大小,那么您要么将内存浪费在空单元格中,要么必须经常调整它们的大小,从而增加代码的复杂性。

于 2012-11-03T12:51:11.900 回答
1

我不记得上次在 Java 中使用数组是什么时候了。我总是使用类似ArrayList或类似的集合。当您处理图像等原始字节时,更使用数组。在内部,集合是使用数组实现的,因此与附加方法(如addputget、 remove 等)基本相同。

回答这个getter/setter问题,如果你正在编写一个将被其他人使用的库,你必须使用 getter 和 setter。用户将使用的接口或层不应该通过简单的属性 ( new A().property) 访问,这是一个非常糟糕的设计,因为您没有封装任何东西。即使您的模块是私有的并且仅由您的应用程序使用,您也必须getters/setters在前端层使用。如果一个类是内部的并且不能从模块/包外部访问,那么可以通过属性访问它,但最好封装。我通过属性访问的唯一情况是当我在公共类中有一个私有类时。我使用属性从公众访问私有类。例子:

public class A{
    B b = new B ();

    private class B{
        String asd = "asd";
    }

    public String a (){
        return b.asd;
    }
}
于 2012-11-03T13:11:04.943 回答