Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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_Performance_Oop_Static - Fatal编程技术网

Java 何时使用静态方法和字段?

Java 何时使用静态方法和字段?,java,performance,oop,static,Java,Performance,Oop,Static,我知道什么是静电,只是不知道什么时候使用它 静态变量: 我只对常量字段使用它。有时一个类中有几十个常量,因此使用静态常量可以节省大量内存。还有其他典型的用例吗 静态方法: 我在上关于算法的课时会用到它。例如,提供不同排序算法的类。这是反对面向对象设计的吗?我认为最好保持这种方式,而不是在需要使用排序算法的每个类中实现排序算法。我错了吗?哪些是好的用例 另外,使用静态字段/方法和非静态字段/方法之间是否存在性能差异?静态变量属于一个类,因此由所有对象共享,因此如果确实希望共享变量,则内存使用量会减

我知道什么是静电,只是不知道什么时候使用它

静态变量: 我只对常量字段使用它。有时一个类中有几十个常量,因此使用静态常量可以节省大量内存。还有其他典型的用例吗

静态方法: 我在上关于算法的课时会用到它。例如,提供不同排序算法的类。这是反对面向对象设计的吗?我认为最好保持这种方式,而不是在需要使用排序算法的每个类中实现排序算法。我错了吗?哪些是好的用例


另外,使用静态字段/方法和非静态字段/方法之间是否存在性能差异?

静态变量属于一个类,因此由所有对象共享,因此如果确实希望共享变量,则内存使用量会减少。如果将变量声明为public和static,那么它对所有人都是全局可用的


静态方法通常是实用方法,具体取决于访问修饰符,它们可以在类内使用,也可以跨类使用。静态实用程序类将有助于再次减少内存使用,因为您不需要创建对象来调用这些方法。

我个人的经验法则是静态的东西“只是挂在那里”。它们是全局性的(免责声明,不完全正确),但包含在这个特定类中是有意义的


如果您发现自己反复加载一些重量级对象,静态字段是很好的。例如,我正在处理的项目现在有两个图像之间的切换。这些是应用程序加载并保存在内存中的静态字段,而不是每次都重新加载它们,让GC来处理混乱情况。

您描述的是使用静态,但这并不能从根本上解释为什么要使用静态和非静态-它们不仅仅是常量和实用方法的关键字

如果某个对象不是静态的(实例),则意味着该类的每个实例都有一个实例。每一个都可以独立地改变

如果某个对象是静态的,则表示该类的所有实例只有一个副本,因此从任何位置更改该对象都会影响所有其他对象

静态变量/方法通常使用更少的内存,因为不管类的实例有多少,它们只有一个副本。如果使用得当,静力学在面向对象设计中是完美的

如果您有一个只需要一个实例的方法/变量(例如常量或实用程序方法),则只需将其设置为静态。但是要理解,使一个方法成为静态意味着它不能被重写。因此,如果您想在子类中重写一个方法,那么不要将其设置为静态


一般的经验法则是——如果你只需要一个副本,就让它成为静态的。如果每个实例都需要一个副本,那么就让它成为非静态的。

还有其他典型的用例吗

全局变量

这是反对面向对象设计的吗

不确切地说,关键是静态方法是无状态的,因为您不需要类的特定实例。我最喜欢的方法是实用方法(比如apachecommons)。但是您可能知道,有些方法可能更适合作为类成员而不是静态的

此外,一旦不能重写这些方法或用模拟实现替换,静态方法会使类的可测试性变得更难

性能差异

谷歌(Google)提出了一项Android性能建议,称“宁愿静态也不要虚拟”:

我不确定这是否适用于JVM,因为Android使用不同的VM,但鉴于链接指出的原因,这是有意义的:

如果不需要访问对象的字段,请将方法设置为静态。调用速度将提高15%-20%。这也是一个很好的实践,因为从方法签名可以看出调用方法不能改变对象的状态。”


除了非常特殊的情况外,我只对常量使用静态(和最终)变量。当然,使用它们是完全有效的


我倾向于避免使用静态实用工具方法,因为它们使代码编写单元测试变得更加困难(模拟方法调用的结果)。当您开始以测试驱动的方式开发时,这个问题变得非常明显。我更喜欢使用依赖项注入和单例bean(尽管这取决于您的需要和情况).

在所有对象中,
静态字段
有一个值,它们称之为类成员,因为它与类相关

  • 您可以将static field用作实用程序

    举个例子,假设我们需要知道有多少个实例:

计数器

     public class Counter {


     public static int instanceCount ;

        public Counter()
        {
            instanceCount++;
        }

        public int getInstanceCount()
        {
            return instanceCount;
        }



    }
创建两个
计数器
类实例后。但它们共享相同的
instanceCount
字段,因为它是一个静态字段,所以
instanceCount
的值在
第一个计数器
第二个计数器
中相同

类别
main

       Counter firstCounter = new Counter();
       // will print 1
       System.out.println(co.getInstanceCount());
       // will print 2
        Counter secondCounter = new Counter();

        System.out.println(co1.getInstanceCount());

静态类级方法,非静态对象级方法默认静态是全局变量。它们是两种不同的东西。私有静态变量可以是类常量,但这并不使其成为全局变量。全局变量通常违反OOP,而静态不是。在这种情况下,将
SoftReference
存储到图像中,并如果垃圾回收器清除了引用..+1,则对它们施加压力。这是唯一一个试图回答性能问题的人,尽管我想知道pc上的性能差异。
静态
并不意味着方法的
最终
。它仍然可以被覆盖(称为“隐藏”),但调用的类方法取决于调用它的类。重写和隐藏与链接中描述的不同。我认为某些东西限制了对某些东西的编程