2012-08-10 61 views
20

所以我的编码器朋友讨厌使用static编码。然而我的Java程序充满了它在类之间的联系,而且我有很多它们!Java静态与实例

是否值得重写整个代码来移除静态方法?

使用一个比另一个有什么优势吗?

+2

我发现使用静态变量保持状态使得程序不可维护,这基本上就像使用全局变量。由于没有任何代码可以从任何地方访问代码,即类别代码,因此类中的私有静态代码不会有同样的问题。 – 2012-08-10 18:25:48

回答

33

1.一个实例变量是每个对象一个,每一个对象具有实例变量的其自己的副本。

如:

public class Test{ 

    int x = 5; 

} 

Test t1 = new Test(); 
Test t2 = new Test(); 

两个t1t2有它自己的x副本。

2.静态变量是类共享相同的静态变量的每一个对象每一个,

如:

public class Test{ 

    public static int x = 5; 

} 

Test t1 = new Test(); 
Test t2 = new Test(); 

两个t1t2将有只有一个X在它们之间共享。

3.当JVM加载类时,会初始化一个静态变量。

4.static method不能访问Non-static变量或方法。

5.Static methodsStatic variables可以模仿一个Singleton Pattern一起,但这不是正确的方式,如当有很多类,那么我们不能肯定的类加载顺序JVM,这可能会造成问题。

+4

我不认为问题是什么是静态变量以及它们为什么不好。这是否值得去除他的编码器朋友说的不好的静态变量。 – 2012-08-10 18:57:25

+4

我已经描述了它们是什么以及它们如何与类相关联。现在它由编码员朋友决定是否使用或不使用......我在第五点中也提到它有时会变得糟糕 – 2012-08-11 09:14:44

7

static是,你不希望有一份为每个实例

instance变量是您要为对象的每个实例单独副本案件的情况。

根据业务案例,使用哪一个可能会改变。

+0

问题是静态字段通常是代码嗅觉的一个实例。特别是OP提到的,因为它们用于类之间的通信,所以它们基本上是全局变量。我远离任何不是只读的公共静态变量。 – 2012-08-10 18:23:49

+0

@JuanMendes:同意你的评论。 – kosa 2012-08-10 18:29:46

+0

这和将它用于函数和变量一样吗? – Kezz101 2012-08-10 19:39:21

3

垃圾收集 - 静态字段的寿命比实例字段长得多。 从逻辑的角度来看,静态字段是ONLy假设在每个实例之间共享的 - 如果它确实是你的情况,那么当然没有问题。

+1

我认为你的观点是公共静态变量是坏的(除了常量) – 2012-08-10 18:53:30

+0

@JuanMendes所以真实!应该提到这一点。谢谢 – Eugene 2012-08-10 18:54:57

4

如果你有太多的静态函数和变量,它可能会导致更多的功能,而不是真正的OO。此外,如果你有公共静态变量,那么你复制不好的全局变量。跟踪它们是一场噩梦。

通常我的原则是,如果你能使用实例变量,只有具有静态变量和函数,如果真的是在一个类,而不是一个对象一般

这是一个相当好的回答一个类似的问题 Java: when to use static methods

不仅仅是链接到方法,而是考虑使用新操作来创建一个新对象并以非静态方式从中访问该方法。

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。

+0

那么公共静态变量究竟有什么不好呢? – Kezz101 2012-08-11 14:14:18

+0

麻烦的是,他们模仿全局变量。这些代码可以在代码中的任何地方更新,这使得很难跟踪哪里更新以及它们处于什么状态。它可能会导致很难找到的错误。这个链接很好解释它。 http://c2.com/cgi/wiki?GlobalVariablesAreBad如果你想更清晰的让我知道 – RNJ 2012-08-12 21:26:29

+0

啊,我现在明白了!感谢您的确认:D – Kezz101 2012-08-13 15:03:01

0

当你使用静态对象(除了单例情况),你实际上正在实现与全局变量相结合的函数式编程。如果你这么做 - 你应该重新考虑你的设计或使用Java(也许你应该使用功能性编程语言,如列表,方案等)。

1

你说的是静态方法还是静态属性?

就静态方法而言,只有一种方法可以滥用它们,那就是当您定义将对象实例作为参数的方法时。你不应该这样做,我认为这样做是不好的编码习惯。这里有一个例子:

static int add(ThisClass a, ThisClass b) { 
    return a.value + b.value; 
} 

如果你在谈论在类的静态变量,你基本上到这是那里的目的是只有一个特定类的实例“单身”的主题。单身人士受到很多虐待。它们被许多类库(认为JDNI和日志记录类)使用,但是如果应用程序广泛使用它们,它可能是一个结构不良的程序的标志。这可能是你的朋友所憎恨的。

0

临静态

一旦静态构件从内部或类的外部,那么类的静态构造函数被调用调用。 “静态对象”将贯穿整个会话,因此您将赢得表现。

精读静态

静态成员不能有状态,因此他们不能谈论到类的非静态成员。

如果我们考虑BigInteger class,这个类如果某些部分被做成静态成员将获得

该类的一个实例表示(如预期的)一个大整数。

但是,主要的方法增加和乘法不是静态的(它们应该处于更好的世界),这对性能不利。

因此,在实践中,人们不应该害怕静态和非静态之间的混合。

0

我不喜欢使用静态变量或方法,因为它们没有真正的继承。这使得嘲笑测试变得更加困难。使用实例为您提供了完全多态的灵活性。另一方面,有时需要静态变量,例如全局缓存。如果静态方法为您无法访问或扩展的类/对象/基元提供辅助方法,那么这些方法可能会有所帮助。这些辅助方法非常简单,不需要继承。例如java.util.Arrays类或java.util.Collections。

1

实例和静态变量:

回答你的问题:我会说这是值得使用静态变量来节省内存分配。

内存分配:

对于静态变量仅一个存储位置被分配irespective没有创建的对象和用于实例变量每个对象一个存储器位置分配

现在考虑该例子中,考虑你正在从事公司内部项目,你必须创建1M对象到员工类和某些属性到员工类是e id,ename,ecompany现在重要的事情是,所有员工都在XYZ公司如此重视财产ecompany将是“XYZ”,不论员工。

现在你知道的情况下,价值的财产企业网站管理系统是要去XYZ 100万级的对象。

现在,您决定要声明ecomapny财产作为静态或实例考虑内存分配

,如果你把它声明为分配给企业网站管理系统静态然后最小内存将只有48字节,这非常少的比较到需要存储1百万个实例变量的内存。 100000 * 48字节= 48百万字节。