Java静态与实例
所以我的编码器朋友讨厌使用static
编码。 然而,我的Java程序充满了它在类之间的链接,我有很多它们!
是否值得重写整个代码来删除静态方法?
使用一个优于另一个是否有任何优势?
1.实例变量是每个Object一个 ,每个对象都有自己的实例变量副本。
例如:
public class Test{ int x = 5; } Test t1 = new Test(); Test t2 = new Test();
t1
和t2
都有自己的 x
副本 。
2.静态变量是每个类 一个,该类的每个对象共享相同的静态变量。
例如:
public class Test{ public static int x = 5; } Test t1 = new Test(); Test t2 = new Test();
t1
和t2
都将在它们之间共享一个x。
3.当JVM加载类时,初始化静态变量。
static method
不能访问Non-static
变量或方法。
5. Static methods
和Static variables
可以模仿 Singleton Pattern
,但是IT不是正确的方式 ,就像有很多类时那样,我们无法确定JVM的类加载顺序,这可能会创建一个问题。
static
适用于您不希望为每个实例复制的情况
instance
变量适用于您希望为每个对象实例单独复制的情况。
根据业务案例,使用哪一个可能会发生变化。
如果你有太多的静态函数和变量,它可以导致更实用的方法,而不是真正的OO。 此外,如果您有公共静态变量,那么您复制的全局变量并不好。 跟踪他们是一场噩梦。
一般来说,我的规则是使用实例变量,如果你可以而且只有静态变量和函数,如果它真的是generics而不是一个对象
对于类似的问题Java来说这是一个很好的答案:什么时候使用静态方法
而不是仅仅链接到方法考虑使用新操作来创建新对象并以非静态方式从该方法访问该方法。
之前
public void myMethod(){ Time.setTime(Time.getTime() + 20); System.out.println(Time.getTime()); }
后
public void myMethod(){ Time t = new Time(); t.setTime(t.getTime() + 20); System.out.println(t.getTime()); }
现在,在这些方法中保存的任何状态都是您创建的时间的实例。 如果需要,您还可以与其他方法共享变量t。
垃圾收集 – 静态字段比实例字段长得多。 从逻辑的角度来看,静态字段是ONLy,假设在每个实例之间共享 – 如果它确实是你的情况,那么当然没有问题。
你在谈论静态方法还是静态属性?
就静态方法而言,只有一种方法可以滥用它们,即定义将对象实例作为参数的方法。 你永远不需要这样做,在我看来这样做是不好的编码实践。 这是一个例子:
static int add(ThisClass a, ThisClass b) { return a.value + b.value; }
如果你在讨论类中的静态变量,那么你基本上就是“单身人士”的主题,而这些主题只是一个特定类的一个实例。 单身者受到很多虐待。 它们被许多类库使用(想想JDNI和日志记录类),但如果应用程序大量使用它们,它可能是程序结构不良的标志。 这可能是你的朋友所喋喋不休的。
实例和静态变量:
回答你的问题:我想说使用静态变量来节省内存分配是值得的。
内存分配:
对于静态变量,只分配一个内存位置,而不是创建对象,并且对于Instance变量,每个对象分配一个内存位置
现在考虑这个例子,考虑你正在处理公司内部项目,你必须在Employee类中创建1M对象,而Employee类的一些属性是eid,ename,ecompany现在重要的是所有员工都在XYZ公司工作所以值得无论员工如何, ecompany都将成为“XYZ”。
现在你知道了这种情况,属性ecompany的值将是1百万对象的XYZ 。
现在,您决定要将ecomapny属性声明为静态或实例,并考虑内存分配
如果将其声明为静态,那么分配给ecompany的最小内存将只有48个字节,这与存储1百万个实例变量所需的内存相比要少得多。 100000 * 48字节= 4800万字节。
当您使用静态对象时(除了单例的情况),您实际上是在实现与全局变量结合的函数式编程。 如果你做了很多 – 你应该重新考虑你的设计或使用Java(也许你应该使用function编程语言,如列表,方案等)。
Pro Static
一旦从类的内部或外部调用静态成员,就会调用该类的静态构造函数。 “静态对象”将贯穿整个会话,因此您将在性能上获胜。
Con Static
静态成员不能拥有状态,因此他们无法与类的非静态成员通信。
例
如果我们考虑BigInteger类 ,如果将某些部分组成静态成员,则该类将获得 。
该类的实例表示(如预期的)一个大整数。
但是,主要方法的加法和乘法不是静态的(它们应该在更好的世界中),这对性能不利。
因此,在实践中,人们不应该害怕静态和非静态之间的混合。
我不喜欢使用静态变量或方法,因为它们没有真正的inheritance。 这使得模拟测试变得更加困难。 使用实例为您提供了完全多态的灵活性。 另一方面,有时需要静态变量,例如使用全局高速缓存。 如果静态方法为您无法访问或扩展的类/对象/基元提供辅助方法,则它们可能是有益的。 这些辅助方法非常简单,不需要inheritance。 例如java.util.Arrays类或java.util.Collections。