猿问

如何为类中的私有变量定义“好的”get() 方法?

我正在学习Java,我有一些疑问。如果定义了一个带有私有变量的类


class test<A>{

private A var;

...

public A get(){

    return var;

}

}


是get方法错了吗?我认为是这样,因为有了这个定义,我可以像这样修改变量“var”


test<A> x = new test<A>();


A temp = x.get();


temp.set(*something*);

最后 x 被更改(我使用 Vector 作为 A 对其进行了测试)。如果我理解正确的话,这是有效的,因为对象引用(我想念 C 指针,sob)。我错了吗?可能我不明白关键字“private”的用途!提前致谢!


编辑:我对“按引用传递”和“按值传递”没有问题。我怀疑在类中为私有变量定义 get() 方法(你不说?)。请停止链接Java 是“按引用传递”还是“按值传递”?


偶然的你
浏览 127回答 4
4回答

陪伴而非守候

如果您的 getter 方法返回对可变对象的引用,那么这会大大削弱您的类提供的封装质量,因为可以在不调用类的方法的情况下修改类实例的状态。防止此问题的一种标准策略是 J. Bloch 所说的防御性副本(Effective Java,第 3 版,第 50 项:“在需要时制作防御性副本”)。var这意味着在 getter 方法中创建一个副本,然后返回该副本。如何做到这一点取决于A.因为A是类型参数,制作实例的副本需要设计上的额外支持。要了解如何使用 Java 的克隆机制实现此目的,请参阅我对帖子“创建类型接口而不是使用有意义吗?”的回答。CopyableCloneable

慕慕森

我要在这里补充一点:正如其他人所说,您分发对象引用并且可以对其进行修改,这可能很糟糕。面向对象是关于将数据和处理数据的代码保存在一个地方。如果您需要 getter,请考虑 getter 的调用者需要做什么,以及该操作是否应该是具有数据的类上的方法。您的代码可能会遇到Feature Envy代码异味,因为它违反了告诉,不要询问原则。要解决此问题,请移除 getter,并根据需要引入新方法。例如,如果您有一些需要打印的数据对象,您可以将 Printer 传递给对象并让它自己打印到给定的 Printer。如果你正在处理一个集合类(只是从你的模板参数中猜测),你可能需要保留 getter,但是你可能并不关心调用者无论如何都会改变值。

侃侃无极

对于刚开始的人来说,这可能有点过于详细,但您可能会回顾 class java.util.concurrent.atomic.AtomicReference<V>,这与您的示例非常相似。一般来说,将实例变量放在私有变量中,同时使用 getter 和 setter 提供对变量的访问是标准做法。请注意,您的类名应该大写,类型参数“V”更标准,变量名通常是“值”。此外,尝试为班级选择一个更具交际性的名称。(类型参数类型变量可以是“ValueType”,这符合某些偏好。但是,单个字符类型变量名称更常见。)public class Wrapper<V> {&nbsp; &nbsp; private V value;&nbsp; &nbsp; public V get() {&nbsp; &nbsp; &nbsp; &nbsp; return value;&nbsp; &nbsp; }&nbsp; &nbsp; public void set(V value) {&nbsp; &nbsp; &nbsp; &nbsp; this.value = value;&nbsp; &nbsp; }}

肥皂起泡泡

如果这是一个问题,您可以创建一个外观来保护您的变量public class Facade extends A {&nbsp; A myObj;&nbsp; public Facade (A obj) {&nbsp; &nbsp; myObj =&nbsp;&nbsp; }&nbsp; public A get(){&nbsp; &nbsp; return myObj.get();&nbsp; }&nbsp; public B set(Object val) {&nbsp; &nbsp; throw new RuntimeException("Setting is not allowed");&nbsp; }}
随时随地看视频慕课网APP

相关分类

Java
我要回答