简体   繁体   English

将'final'修饰符与getter和setter一起使用是一个好主意吗?

[英]Is it a good idea to use 'final' modifier with getters and setters?

I was wondering why the final modifier is not used with getters and setters? 我想知道为什么最终修饰符不与getter和setter一起使用?

Why do this: 为什么这样:

private int x;

public void setX(int x) 
{ 
  if(x >= 1) throw new IllegalArgumentException("X must be lower than 1");
  this.x = x; 
}

Instead of this: 而不是这个:

private int x;

public final void setX(int x) 
{ 
  if(x >= 1) throw new IllegalArgumentException("X must be lower than 1");
  this.x = x; 
}

It does not improve the encapsulation? 它没有改善封装? I have been trying to clarify it with google but I had not luck. 我一直试图用谷歌澄清它,但我没有运气。

Thanks by advance. 谢谢你提前。

One reason that you may want to leave a setter non-final is to let subclasses make their own, stricter, argument checks: 您可能希望离开setter非final的一个原因是让子类进行自己的,更严格的参数检查:

public class Subclass extends Superclass {
    public void setX(int x) { 
        if(x >= 0) throw new IllegalArgumentException("X must be negative");
        super.setX(x); 
    }
}

Of course this breaks Liskov Substitution Principle , because a subclass strengthens a precondition in a subtype. 当然这打破了Liskov Substitution Principle ,因为子类强化了子类型中的前提条件。

The purpose of a final method in Java, is that it cannot be overridden or hidden by subclasses. Java中最终方法的目的是它不能被子类覆盖或隐藏。 Hence if you need that functionality for your getters / setters, it's perfectly fine to make them final, else there is no purpose for doing so. 因此,如果您需要为getter / setter提供该功能,那么将它们作为最终版本是完全正确的,否则没有任何目的。

I would strictly avoid setters when there may be another more robust possibility: 当可能存在另一种更强大的可能性时,我会严格避免使用setter:

You may want to provide a setter in case you want to mutate a field. 如果要改变字段,可能需要提供setter。

Issue you mentioned: 你提到的问题:

What if a developer breaks the validation rules I provided, by overriding the setter...Should we go with final keyword? 如果开发人员通过覆盖setter来破坏我提供的验证规则,那该怎么办...我们应该使用final关键字吗?

I would say: "Dissuade him to do so" . 我会说: “不要他这样做”

Indeed, declaring a setter is like saying to the world: 事实上,宣布一个二传手就像对世界说:
"You can provide me some field value and then you can do your own thing with me !" “你可以为我提供一些实地价值,然后你可以跟我做自己的事!” => procedural code =>程序代码

"Tell! Don't ask" philosophy would say: “告诉!不要问”哲学会说:
"Client, tell me what to do, I will do." “客户,告诉我该怎么做,我会做的。”
And in general, your main "complex" logic would be in the main public api of the POJO. 一般而言,您的主要“复杂”逻辑将位于POJO的主要公共API中。

I doubt that a developer would be tempted to override the full logic of a POJO without risking complete bad behaviors.. 我怀疑开发人员是否会试图覆盖POJO的完整逻辑而不会冒完全不良行为的风险。

So, for instance, instead of declaring an opened setter to any value, force the value to be passed on the main method, so that you can control the flow: 因此,例如,不是将打开的setter声明为任何值,而是强制将值传递给main方法,以便您可以控制流:

public void computeWith(int x) {
  if(x <= 0) throw new IllegalArgumentException("X must be superior to 0");
  //code computing here.
}

You will notice that some fields might even not be needed any more in the POJO with this way of doing. 您会注意到POJO中的某些字段甚至可能不再需要这种方式。

To sum up: It's easy to override a poor validation rule...but risky for a behaviour. 总结一下:很容易覆盖一个糟糕的验证规则......但对于一个行为是有风险的。

Just my 2 cents. 只需2美分。

There are arguments both ways but if you make methods final (of any sort, not just getters or setters), somewhere down the line another developer will cursing you. 两种方式都存在争议,但如果你将方法设为最终(任何类型,不仅仅是getter或setter),那么另一位开发人员会诅咒你。 It's very hard to predict how your class will be used in the future and restricting it by making it final usually makes like more difficult for a future developer. 很难预测你的课程将来会如何使用,并且通过最终决定来限制它通常会让未来的开发人员变得更加困难。

eg some poor soul has got to integrate your code with a new application the company has just bought. 例如,一些可怜的灵魂必须将您的代码与公司刚购买的新应用程序集成。 It's 3pm on Friday afternoon and the demo is due on Monday morning. 星期五下午3点,演示将在周一早上到期。 If only they could override a getter, they could force it to return a wrapped object from the new application and things would work. 如果只有他们可以覆盖一个getter,他们可以强制它从新的应用程序返回一个包装的对象,事情会起作用。 If that getter is final, they have to start changing, testing may be releasing your code so they end up working over the weekend. 如果那个getter是最终的,他们必须开始改变,测试可能会释放你的代码,所以他们最终在周末工作。

So have some sympathy with future developers and don't make methods final unless you are really really sure. 所以对未来的开发者有一些同情,除非你真的确定,否则不要让方法最终。 Even then I wouldn't bother. 即便如此,我也不会打扰。

Another use specifically for non-final getters is testing. 专门用于非最终吸气剂的另一种用途是测试。 It can be very convenient, particularly during integration tests with less than perfect code, to override a getter to inject a test instance of a class. 它可以非常方便,特别是在使用不完美代码的集成测试期间,覆盖getter以注入类的测试实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM