有一个不使用实例变量的非静态方法是否有意义?

Chi*_*led 29 java methods static instance non-static

编译器不允许静态方法调用非静态方法.我理解这样做是因为非静态方法通常最终使用实例变量.

但是有一个不使用实例变量的非静态方法是否有意义.如果我们的行为不影响或不受实例状态的影响,则不应将此类方法标记为静态.

Jas*_*zun 30

好吧!我们假设你有interface IMyCollection.它有一种方法boolean isMutable().

现在你有两个班,class MyMutableListclass MyImmutableList,这既实现IMyCollection.他们每个人都会覆盖实例方法isMutable(),MyMutableList只需返回trueMyImmutableList返回false.

isMutable()在这两个类中都是一个实例方法,(1)不使用实例变量,(2)不影响实例状态.但是,由于语言的限制(无法覆盖静态方法),这种设计是唯一实用的设计.

另外,我想澄清一个误解(正如@manouti所做的那样):非静态方法不是实例,因为它们使用任何实例变量或影响实例状态; 它们是实例方法,因为它们是以这种方式定义的(没有static关键字),因此有一个隐式this参数(在像Python这样的语言中,它实际上是显式的!).


ysh*_*vit 25

通常,没有.如果方法没有触及任何实例状态,则没有理由将其绑定到实例.

当然,静态方法不能被继承或覆盖,因此,您可能希望拥有一个不使用实例状态的实例方法.该策略模式就是一个典型的例子.

无论如何,您可以将它绑定到实例的另一种情况是,如果这是一个公共API,并且您可能想要将该方法绑定到将来的实例状态.在这种情况下,使用API​​的人员的向后兼容性问题可能会使(或不可能)将静态方法转换为实例方法.

  • API参数是这里最重要的一点.`static`方法不能从继承的接口实现方法.`static`方法不受多态性的影响.事实上,`static`方法的能力非常有限. (3认同)

Eri*_*son 7

由于无法覆盖静态方法,因此许多关注其代码可测试性的开发人员试图完全避免使用Java中的静态方法.

如果依赖项可以替换为mock对象,则代码更易于测试.和的Mockito EasyMock的是最常见的工具来解决这个问题,他们靠继承创建的子类,让您可以轻松地越过你的(通常是复杂的)方法希望测试......这样你的测试重点是你想做什么测试.

我不会尝试使用零静态方法,但是当我承认包含它们时,我常常后悔,出于测试原因.

所有这一切都非常令人沮丧,因为它与静态vs实例方法的设计考虑无关.这让我希望那些允许你拥有与课程无关的功能的语言......


sup*_*cat 7

如果一个人正在编写方法目的的人类可读描述,它会提到一个对象吗?如果是这样,请使用实例方法.如果不是,请使用静态方法.请注意,某些方法可能以任何一种方式描述,在这种情况下,应该使用判断哪个含义更好.

例如,考虑"获取应该邮寄Freedonian所得税表格的地址"与"获取Freedonian所得税表格应邮寄的地址"?第一个问题应该通过实例方法来回答; 第二种是静态方法.可能是Freedonia目前要求将所有税表发送到同一地址(在这种情况下,前一种方法可能会忽略所有实例字段),但将来可能会为不同地区的人员设置不同的办公室(在这种情况下,前一种方法)可能会查看纳税人ID并根据该地址选择邮寄地址,而后一种方法则必须将表格指向办公室,办公室可以接受任何人的表格并根据需要重定向.