java POJO 中是否有必要有 getter 和 setter
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7455630/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it necessary to have getters and setters in POJO's
提问by tintin
I have been going through clean code book which states that the class should not expose the internal state of its data and only should be exposing the behavior. In case of a very simpl and dumb java bean exposing the internal state which getter's and setters, is it not worth just removing them and make the private members public? Or just treat the class as a data structure?
我一直在浏览干净的代码手册,其中指出该类不应公开其数据的内部状态,而应仅公开行为。如果一个非常简单和愚蠢的 java bean 暴露了 getter 和 setter 的内部状态,是否不值得仅仅删除它们并使私有成员公开?或者只是将类视为数据结构?
回答by Destroyica
I don't think so. It depends of the lifetime of your Object and its "exposure" (external modification).
我不这么认为。这取决于对象的生命周期及其“暴露”(外部修改)。
If you're only using it as a data structure, exposing fields in secure way (final) sounds enough:
如果您仅将其用作数据结构,以安全方式(最终)公开字段听起来就足够了:
public class Person {
public final String firstName;
public final String lastName;
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
回答by Peter Lawrey
The term POJO was intended to distinguish classes from JavaBeans or any other convention. As such a POJO is by definition NOT required to do anything.
术语 POJO 旨在将类与 JavaBeans 或任何其他约定区分开来。因此,根据定义,POJO 不需要做任何事情。
I have been going through clean code book which states that the class should not expose the internal state of its data and only should be exposing the behavior.
我一直在浏览干净的代码手册,其中指出该类不应公开其数据的内部状态,而应仅公开行为。
This is called encapsulation and a good principle.
这就是所谓的封装,也是一个很好的原则。
In case of a very simpl and dumb java bean exposing the internal state which getter's and setters, is it not worth just removing them and make the private members public?
如果一个非常简单和愚蠢的 java bean 暴露了 getter 和 setter 的内部状态,是否不值得仅仅删除它们并使私有成员公开?
That is an alternative approach. Some projects may forbid this approach while others may encourage it. Personally, I would favour this approach for classes which are encapsulated in some way already e.g. they are package local.
这是一种替代方法。一些项目可能会禁止这种方法,而另一些项目可能会鼓励它。就个人而言,对于已经以某种方式封装的类,例如它们是本地包,我更喜欢这种方法。
There is a view that some day in some way your class might have additional requirements and changing the "API" will be impossible. This goes against the YAGNI principle and very rarely proves to be the case and when it does has a much lower cost than adding lots of methods which don't do anything.
有一种观点认为,有一天你的班级可能会有额外的要求,改变“API”是不可能的。这与 YAGNI 原则背道而驰,而且很少被证明是这种情况,而且与添加许多不做任何事情的方法相比,这样做的成本要低得多。
However, this is not always the case and if you don't use accessor methods you should consider what the impact will be on the project if you have to change it later. Using accessor methods every where means you never need to worry about this.
然而,情况并非总是如此,如果您不使用访问器方法,您应该考虑如果以后必须更改它会对项目产生什么影响。在任何地方使用访问器方法意味着你永远不需要担心这个。
In summary, if you are pretty sure accessor methods are pointless and it won't be a problem to add them later, I would say you should use your judgement. However if you are not sure if it could be a problem in the future or you don't want to have to worry about it, use accessor methods.
总之,如果您非常确定访问器方法毫无意义并且以后添加它们不会有问题,我会说您应该使用您的判断。但是,如果您不确定将来是否会成为问题,或者您不想担心它,请使用访问器方法。
回答by Luigi R. Viggiano
The definition of POJO doesn't mandate getter/setter.
POJO 的定义不强制使用 getter/setter。
Experimentally, I am not using getter and setter in my current project.
实验上,我没有在我当前的项目中使用 getter 和 setter。
The approach I am taking is this one:
我采取的方法是这样的:
unless necessary, don't provide getter/setter.
除非必要,否则不要提供 getter/setter。
So far, I didn't find a case where I really needed get/set.
到目前为止,我还没有找到真正需要 get/set 的情况。
Some friend told me: "having get/set is helpful if in the future you need xyz"; my reply has been: when -in the future- I need to do so, I will provide the getter and setter; I don't want to anticipate anything.
一些朋友告诉我:“如果将来需要 xyz,拥有 get/set 会很有帮助”;我的回答是:当 - 将来 - 我需要这样做时,我会提供 getter 和 setter;我不想期待任何事情。
The objection about incapsulation, that some may raise, is not really a valid one: providing getter and setter breaks incapsulation in the same manner, plus you have additional lines of (useless) code. Bugs may also lay in getter and setters.
有些人可能提出的关于封装的反对意见并不是真正有效的:提供 getter 和 setter 以相同的方式破坏封装,而且你有额外的(无用的)代码行。错误也可能存在于 getter 和 setter 中。
This is an example of one of a non-trivial domain class:
这是一个非平凡域类的示例:
public class SSHKey implements IsSerializable {
public Long id;
public Long userId;
public String type;
public String bits;
public String fingerprint;
public String comment;
@SuppressWarnings("unused")
private SSHKey() { // required by gwt-rpc
}
public SSHKey(String text) throws InvalidSSHKeyException {
Ensure.that(text != null, new InvalidSSHKeyException("Invalid Key"));
text = text.trim();
String[] parts = text.split(" ", 3);
Ensure.that(parts.length >= 2,
new InvalidSSHKeyException("Invalid Key"));
type = getType(parts);
Ensure.that(type.equals("ssh-rsa") || type.equals("ssh-dss"),
new InvalidSSHKeyException(
"Key must start with 'ssh-rsa' or 'ssh-dss'"));
bits = getBits(parts);
comment = getComment(parts);
}
private String getBits(String[] parts) {
return parts[1];
}
private String getComment(String[] parts) {
if (parts.length == 3)
return parts[2];
return type + " " + bits.substring(0, min(15, bits.length())) + "...";
}
private String getType(String[] parts) {
return parts[0];
}
}
The constructor takes the responsibility to validate and prepare the data to be manageable. Thus this logic doesn't need to be in a setter/getter.
构造函数负责验证和准备可管理的数据。因此,此逻辑不需要在 setter/getter 中。
If I was shown object with public members some years ago, I would probably not like them; maybe I am doing something wrong now, but I am experimenting and so far it is ok.
如果几年前我对公众成员表示反对,我可能不会喜欢他们;也许我现在做错了什么,但我正在试验,到目前为止还可以。
Also, you need to consider if your class is designed to be extended or not (so, foresee the future is part of the requirements), and if you want your object to be immutable. Those things you can only do with get/set.
此外,您需要考虑您的类是否设计为可扩展的(因此,预见未来是要求的一部分),以及您是否希望您的对象是不可变的。那些你只能用 get/set 做的事情。
If your object must be immutable, and you can avoid the empty constructor, you can just add 'final' to the member instances, btw. Unfortunately I had to add IsSerializable (similar to java.io.Serializable) and an empty constructor since this is required by gwt. So, you could tell me then "you see? you need the getter an setter"; well not so sure.
如果您的对象必须是不可变的,并且您可以避免使用空的构造函数,那么您只需将“final”添加到成员实例中,顺便说一句。不幸的是,我不得不添加 IsSerializable(类似于 java.io.Serializable)和一个空的构造函数,因为这是 gwt 所必需的。所以,你可以告诉我“你明白了吗?你需要 getter 和 setter”;不太确定。
There are some jdbc frameworks which promote the use of public fields btw, like http://iciql.comThis doesn't imply that this project is correct, but that some people are thinking about it.
顺便说一句,有一些jdbc框架提倡使用公共字段,例如http://iciql.com这并不意味着这个项目是正确的,但有些人正在考虑它。
I suppose that the need of getter/setter is mostly cultural.
我想对 getter/setter 的需求主要是文化上的。
回答by orip
Only if you expose a class in a library that's used beyond your control.
仅当您在库中公开超出您控制范围的类时。
If you do release such a library, the Uniform Access Principledictates that you should use getters and setters in order to be able to change the underlying implementation later without requiring clients to change their code. Java doesn't give you other mechanisms to do this.
如果您确实发布了这样的库,则统一访问原则规定您应该使用 getter 和 setter,以便以后能够在不需要客户端更改其代码的情况下更改底层实现。Java 没有为您提供其他机制来执行此操作。
If you use this class in your own system, there's no need: your IDE can easily encapsulate a public field and update all its usages in one safe step. In this case, brevity wins, and you lose nothing for the time where you need encapsulation.
如果您在自己的系统中使用此类,则没有必要:您的 IDE 可以轻松封装公共字段并在一个安全的步骤中更新其所有用法。在这种情况下,简洁胜出,并且在需要封装的时间里没有任何损失。
回答by SJuan76
The issue with making the members accessible is that you no longer control them from inside the class.
使成员可访问的问题是您不再从类内部控制它们。
Let's say that you make Car.speed accessible. Now, everywhere in you program there can be some reference to it. Now, if you want to make sure that speed is never set a negative value (or to make the change synchronized because you need to make it thread safe), you have to either:
假设您使 Car.speed 可访问。现在,您程序中的任何地方都可以引用它。现在,如果您想确保速度永远不会设置为负值(或使更改同步,因为您需要使其线程安全),您必须:
in all the points where speed is accessible, rewrite the program to add the control. And hope that everybody that changes the program in the future remembers to do so.
make the member private again, create the getter and setter methods, and rewrite the program to use them.
在所有可以访问速度的地方,重写程序以添加控件。并希望将来更改程序的每个人都记得这样做。
再次将成员设为私有,创建 getter 和 setter 方法,并重写程序以使用它们。
Better get used to write getter and setter from the beginning. Nowadays, most IDEs do it automatically for you, anyway.
最好从一开始就习惯编写 getter 和 setter。如今,无论如何,大多数 IDE 都会自动为您执行此操作。
回答by A.H.
The canonical answer to this is: You don't know whether your simple data structure will stay so simple in the future. It might evolve more than you expect now. It might be also possible, that anytime soon you wantsome "value changed" observer in that bean. With getter and setter methods you can do this very simply later without changing you existing codebase.
对此的标准答案是:您不知道您的简单数据结构将来是否会保持如此简单。它的发展可能超出您现在的预期。也有可能,您很快就会希望该 bean 中出现一些“值已更改”的观察者。使用 getter 和 setter 方法,您以后可以非常简单地完成此操作,而无需更改现有代码库。
Another pro point for getter/setter is: If in Rome, do like the Romans... Which means in this case: Many generic frameworks expectgetter/setter. If you don't want to rule all these usefulls frameworks out right from the start then do you and your colleagues a favour and simply implement standard getter/and setters.
又亲点的getter / setter是:如果在罗马,不喜欢罗马人...这意味着在这种情况下:许多通用的框架预期的getter / setter。如果您不想从一开始就排除所有这些有用的框架,那么帮您和您的同事一个忙,只需实现标准的 getter/和 setter。
回答by tiborka
for the data-type objects, like POJO / PODS / JavaBean, at python you have only public members
you can set those and get those easily, without generating boilerplate setter and getter code(in java these boilerplate code usually(98%) exposes the inner private tag as noted in the question)
and at python in the case you would need to interact with a getter, then you just define extra code only for that purpose
clean and effective at the language level
at java they chose the IDE development instead of changing base java, see JavaBean e.g. how old that is and java 1.0.2 is how old...
JDK 1.0 (January 23, 1996)
The EJB specification was originally developed in 1997 by IBM and later adopted by Sun Microsystems (EJB 1.0 and 1.1) in 1999
so just live with it, use the setter getter because those are enforced by java surroundings
对于数据类型对象,如 POJO/PODS/JavaBean,在 python 中,您只有公共成员,
您可以设置它们并轻松获取它们,而无需生成样板设置器和获取器代码(在 Java 中,这些样板代码通常(98%)公开问题中提到的内部私有标签)
和在 python 的情况下,您需要与 getter 进行交互,然后您只需为此目的定义额外的代码,
在 Java
的语言级别干净有效,
他们选择了 IDE 开发而不是更改基础 java,请参见 JavaBean eg that is and java 1.0.2 is how old...
JDK 1.0(1996 年 1 月 23 日)
EJB 规范最初由 IBM 于 1997 年开发,后来被 Sun Microsystems(EJB 1.0 和1.1) 1999 年
所以只要忍受它,使用 setter getter 因为这些是由 java 环境强制执行的
回答by KarlP
I think it's a good idea to use getters and setters, unless you have very specific speed/memory/efficiency requirements or very simple objects.
我认为使用 getter 和 setter 是个好主意,除非您有非常具体的速度/内存/效率要求或非常简单的对象。
A good example is a Point
, where it is probably both nicer and more efficient to expose it's .x
and .y
variables.
一个很好的例子是 a Point
,在其中公开它的.x
和.y
变量可能更好也更有效。
That said, it will actually not be a big effort to change the visibility of a few member variables and introduce getters and setters even for a large codebase, if you suddenly require some logic in a setter.
也就是说,如果您突然需要 setter 中的某些逻辑,即使对于大型代码库,更改一些成员变量的可见性并引入 getter 和 setter 实际上也不会花费太多精力。
回答by jordenysp
JavaBeans require getters and setters. POJOs do not, anyway this has its benefits
JavaBean 需要 getter 和 setter。POJO 没有,反正这有它的好处
The objetive of the getters and setters is to achieve encapsulation, which manages the internal state of object. This allows you to add or change business rules in your application after the application has been implemented only change the getter or setter code, example, if you have a text field that only allows for more than 3 characters can check before assigning it to an attribute and throw an exception, other reason for not doing this is if it's possible you'll want to change the implementation or change variable names or something like. This cannot be enforced if the field is publicly accessible and modifyable anyway you can use your IDE to generate setters and getters.
getter 和 setter 的目标是实现封装,管理对象的内部状态。这允许您在应用程序实施后添加或更改应用程序中的业务规则,仅更改 getter 或 setter 代码,例如,如果您有一个仅允许超过 3 个字符的文本字段,则可以在将其分配给属性之前进行检查并抛出异常,不这样做的另一个原因是您是否可能想要更改实现或更改变量名称或类似的东西。如果该字段可公开访问和修改,则无法强制执行此操作,无论如何您都可以使用 IDE 生成 setter 和 getter。
If you are developing a simple application can be recommended, if your application is complex and must give maintenance is not recommend.
如果你正在开发一个简单的应用程序可以推荐,如果你的应用程序很复杂并且必须给予维护则不推荐。
回答by I.Cougil
That's the true what @Peter Lawrey explains about encapsulation.
这就是@Peter Lawrey 关于封装的解释。
Only one note: it's more important, when you are working with complex objects (for example in the domain model in a ORM project), when you have attributes that aren't simple Java types. For example:
只有一个注意事项:当您处理复杂对象时(例如在 ORM 项目中的域模型中),当您拥有不是简单 Java 类型的属性时,这一点更为重要。例如:
public class Father {
private List childs = new ArrayList();
public Father() {
// ...
}
private List getChilds() {
return this.childs;
}
public void setChilds(List newChilds) {
this.childs = newChilds;
}
}
public class Child {
private String name;
// ...
private String getName() {
return this.name;
}
public void setName(String newName) {
this.name = newName;
}
}
If you expose one attribute (like the childs
attribute in the Father
class) as a public, you won't be able to identify what part of your code are setting or changing one property of your exposed attribute (in the case, for example, adding new Child
to a Father
or even changing the name
of a existing Child
). In the example, only a Father
object can retrieve the childs
content and all the rest of the classes can change it, using its setter.
如果您将一个属性(如类中的childs
属性Father
)公开为公共属性,您将无法识别代码的哪一部分正在设置或更改您公开的属性的一个属性(例如,在这种情况下,添加新的属性)Child
到一个Father
或什至改变name
一个现有的Child
)。在这个例子中,只有一个Father
对象可以检索childs
内容,所有其余的类都可以使用它的 setter 来更改它。