Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 有执行相同任务的静态和实例方法对吗?_Java_Methods_Static_Refactoring_Instance - Fatal编程技术网

Java 有执行相同任务的静态和实例方法对吗?

Java 有执行相同任务的静态和实例方法对吗?,java,methods,static,refactoring,instance,Java,Methods,Static,Refactoring,Instance,在开发二维向量类作为数学库的一部分时,出于风格和可用性的原因,我正在考虑使用静态和实例方法对。也就是说,有两个等价函数,但一个是静态的非变异函数,另一个是实例化的变异函数。我知道我不是第一个考虑这个问题的人(比如说),但是我没有找到任何直接涉及它的信息。 拥有静态和实例方法对的优点: 有些人更喜欢使用其中一种,在某些情况下,能够选择使代码更易于阅读 这意味着,当同时提供静态方法和实例方法时,静态方法不会发生变化。这可以使调用代码更加清晰,例如: someVector = Vector2d.ad

在开发二维向量类作为数学库的一部分时,出于风格和可用性的原因,我正在考虑使用静态和实例方法对。也就是说,有两个等价函数,但一个是静态的非变异函数,另一个是实例化的变异函数。我知道我不是第一个考虑这个问题的人(比如说),但是我没有找到任何直接涉及它的信息。 拥有静态和实例方法对的优点:

  • 有些人更喜欢使用其中一种,在某些情况下,能够选择使代码更易于阅读
  • 这意味着,当同时提供静态方法和实例方法时,静态方法不会发生变化。这可以使调用代码更加清晰,例如:

    someVector = Vector2d.add(vec1, vec2);
    someVector = (new Vector2d(vec1)).add(vec2); // does the same thing although more convoluted.
    
    // similarly adding directly to a vector is simpler with a mutator method.
    someVector.add(vec2);
    someVector = Vector2d.add(someVector, vec2);
    
    这在使用长链函数调用时尤其重要,这在向量中很常见

  • 就地操作在计算上比为每个操作创建新实例更快。用户决定性能何时重要。对于向量类的用户来说,性能可能很重要,因为向量经常用于计算成本很高的代码中

仅使用静态或实例方法的优点,但不能同时使用这两种方法:

  • 没有明显的代码冗余。易于维护

  • 少一点浮肿。javadocs的大小几乎是它的一半

  • 没有必要告诉用户静态方法永远不会变化,非getter实例方法总是变化

拥有静态/实例方法对有多不受欢迎?有没有大型图书馆使用过

“静态方法不会变异,实例方法会变异”的模式是众所周知的吗?

在第一部分,“静态方法不会变异”,这在OOP中被广泛使用。我还没听说过有人明确地表达这一点。但这是常识:“如果你改变了一个对象,如果它可以是一个实例方法,为什么这个方法会是静态的?”所以我完全同意“静态方法不会变异”

在第二部分,“实例方法确实[变异]”,这实际上并没有被广泛使用。这完全取决于您决定您的设计是应用不变性还是可变性。Java API中的示例:
Java.lang.String
是不可变的,
Java.util.Date
是可变的(很可能是意外/糟糕的设计),
Java.lang.StringBuilder
是有意可变的(这就是它的目的)。易变性可能导致防御性克隆,以保护代码不受变异bug的影响。这是否真的是一个问题取决于以下几点:

  • 它是其他人将使用的API吗?你永远不知道他们将如何使用你的代码。。。在我看来,保护API代码不受变异bug的影响比保护普通代码更重要
  • 单元测试覆盖率有多好?你的单元测试会发现所有可能潜入的变异bug吗?如果您正确地遵循TDD(Bob叔叔的TDD三定律),并且它是非API代码,那么在没有立即被发现的情况下,变异bug就不太可能潜入
  • 如果您的代码必须使用防御性克隆来保护自己不受变异bug的影响,那么该代码多久调用一次?如果经常创建防御克隆,那么使用不可变对象可能比使用可变对象更好。基本上,这是关联类的只读方法(最终会进行防御性克隆)的调用数量与类本身上mutator方法的调用数量之比
就我个人而言,我更喜欢不可变对象,我是
final
的粉丝(如果我可以更改Java,我会将
final
作为所有字段和变量的默认值,并引入关键字
var
,使它们成为非final),我尝试用Java进行函数式编程,尽管它不是函数式编程语言,尽可能多。根据我的经验,我知道我花在调试代码上的时间比其他人少得多(实际上,我可能一年左右运行两次Java调试器)。我没有足够的经验数据和适当的分析来创建经验、不变性、函数式编程和正确性之间的任何“因果关系”,因此我只想说我相信不变性和函数式编程有助于正确性,你必须对此做出自己的判断


在第二部分结束时,“实例方法确实[变异]”是广泛使用的假设,以防对象无论如何都是可变的,否则实例方法将被克隆。

我认为您提供静态/不可变和实例/可变方法的概念是一个很好的概念。我认为这种区别很容易解释,API用户也很容易理解和记住

我认为您的API实现代码不会有冗余的业务逻辑。您会发现,您重复了一个模式,其中静态实现创建了一个新实例,并在该新实例上调用instance方法


考虑到我的懒惰,我将考虑构建一个能够在编译时自动生成静态方法、它们的javadoc和它们的单元测试的基础设施。如果你有10个方法的话,这就太过分了,但是如果你有1000个方法的话,这将是一个巨大的胜利。

设计像“2D向量”这样看似微不足道的类确实会带来很多设计挑战。特别是,在方便性和性能(更少的垃圾)之间的权衡,以及在“惯用”用法和诸如不变性之类的东西之间的权衡,使得这比乍一看要困难得多。直到现在还没有答案(如果我写了一个,它必须很长…),但是。。。如果您提供了更多的代码(即,整个类),这可能非常适合。有人可能会认为,使用两个名称相同但语义差异极大的方法可能会让用户感到困惑,从而导致微妙的错误。