简体   繁体   English

静态方法与否? 全局变量?

[英]Static Methods or Not? Global variables?

I want to know what way is more efficient. 我想知道哪种方法更有效。

  1. No global variables, passing variables through parameters, having all methods static 没有全局变量,通过参数传递变量,所有方法均为静态

  2. No global variables, having only main method static and creating class object in main to access methods 没有全局变量,只有main方法静态并且在main中创建类对象以访问方法

  3. Use only global variables, having only main method static and creating class object in main to access methods 仅使用全局变量,仅使main方法静态,并在main中创建类对象以访问方法

I am currently using method 3 but I want to know what is more efficient. 我目前正在使用方法3,但我想知道哪种方法更有效。 This class will not be used by any other class outside of it, it pretty much stands alone. 该类不会被该类之外的任何其他类使用,它几乎是独立的。

Example of my code structure: 我的代码结构示例:

public class myClass {
   private int globalVariable;

   public static void main(String args[]) {
      myClass c;
      c.someMethod(); // Changes global variable from method
      System.out.println(someMethod); // Prints solution
   }

   public void someMethod() {...}
}
  • No class is an island. 没有阶级是孤岛。
  • There are no silver-bullets, at least its very true in programming. 没有银弹,至少在编程中如此。
  • Premature optimisation is the root of all evil. 过早的优化是万恶之源。
  • In Java we don't have global variables. 在Java中,我们没有全局变量。 We only have class variables, instance variables, and method variables. 我们只有类变量,实例变量和方法变量。

[Edit] [编辑]

I am trying to explain here my last point. 我想在这里解释我的最后一点。 In fact, bringing the discussion, that is going-on in comments below, to the actual post. 实际上,将下面的评论中正在进行的讨论带到实际帖子中。

First look at this, an SO thread of C# . 首先看一下C#的SO线程 There folks are also suggesting the same thing, which is, 那里的人们也在暗示着同一件事,那就是,

So, here we go. 所以,我们开始。

retort: Classes are globally scoped, and thus all class variables are globally scoped. 反驳:类是全局范围的,因此所有类变量都是全局范围的。 Hence should be called global. 因此应称为全局。

counter-retort: Not all classes are globally scoped. counter-retort:并非所有类都是全局范围的。 A class can be package-private . 一个类可以是package-private Therefore, the static variables in there will not be visible outside the package. 因此,其中的static变量在程序包外部将不可见。 Hence, should not be called as global. 因此,不应称为全局。 Furthermore, classes can be nested, thus can be private as well and definitely can have some static variables but those wouldn't be called global. 此外,类可以嵌套,因此也可以是private ,并且绝对可以具有一些static变量,但这些变量不会被称为全局变量。

retort: public classes are globally scoped, and thus all class variables are globally scoped. 反驳: public类是全局范围的,因此所有类变量都是全局范围的。

counter-retort: Not exactly. 反退:不完全是。 I would like to move the previous argument here but on a variable level. 我想将前面的论点移到这里,但是要在可变的水平上。 No matter if the class itself is public . 无论班级本身是否public The variables in there can be protected , package-private and private . 其中的变量可以是protectedpackage-privateprivate Hence, static variables will not be global in that case. 因此,在这种情况下, static变量将不是全局变量。

Now, if you like to call public static variable in public static class, as global then call it by any means. 现在,如果要在public static类中将public static变量称为global,则可以通过任何方式调用它。 But consider this, when you create a new ClassLoader (as a child of the bootstrap ClassLoader ) and load a class that you've already loaded. 但是,当您创建一个新的ClassLoader (作为Bootstrap ClassLoader的子级)并加载一个已经加载的类时,请考虑一下这一点。 Then that results in a "very new copy of the class" -- complete with its own new set of static s. 然后得到一个“该类的非常新的副本”-带有自己的一组新的static s。 Very "un-global", indeed. 确实,这是非常“非全球性的”。 However, we don't use the word global in Java because it tends to confuse the things and then we need to come with whole lot of explanations just to make everything clear. 但是,我们在Java中不使用“全局”一词,因为它容易使事情变得混乱,然后我们需要附带很多解释才能使所有内容都清楚。 Folks rightly like to explain the feature of global variables in Java by static variables. 人们正确地喜欢用static变量来解释Java中global变量的功能。 There is no problem in that. 没问题。 If you have some problem/code in any other language and that is using global variables and you need to convert that code to Java, then you most likely make use of static variable as an alternative. 如果您有任何其他语言的问题/代码,并且正在使用全局变量,并且需要将该代码转换为Java,则很可能会使用static变量作为替代。

A couple of examples I like to render here 我想在这里渲染几个例子

  1. When I started Java, instructors like to explain the difference of passing object type variable and primitive variables. 当我启动Java时,讲师喜欢解释传递对象类型变量和原始变量的区别。 And they constantly use the term objects are pass-by-reference , whereas primitives are pass-by-value . 他们经常使用术语“对象是pass-by-reference pass-by-value ,而基元是“ pass-by-value Students found this explanation quite confusing. 学生们发现这种解释相当混乱。 So, we came up with the notion that everything in Java is pass-by-value. 因此,我们想到了Java中的所有内容都是按值传递的概念。 And we explain that for objects references are pass-by-value. 并且我们解释说,对于对象,引用是按值传递的。 It becomes much more clear and simple. 它变得更加清晰和简单。

  2. Similarly, there are languages which support multiple-inheritance. 同样,有些语言支持多重继承。 But Java doesn't, again arguably speaking. 再次有争议的是,Java没有。 But folks tend to explain that feature using interface s. 但是人们倾向于使用interface来解释该功能。 They explain it by class implementing many interfaces, and call it multiple-inheritance. 他们通过实现许多接口的类对它进行解释,并将其称为多重继承。 That's perfectly fine. 很好 But what the class, actually, receives by inheriting a number of interfaces. 但是,该类实际上是通过继承许多接口来接收的。 Frankly speaking, nothing. 坦白说,没事。 Why? 为什么?

    . Because all the variables in interfaces are implicitly public , final and static , which apparently means those belongs to the class and anyone can access those. 因为接口中的所有变量都是隐式的publicfinalstatic ,这显然意味着它们属于该类,并且任何人都可以访问它们。 Now we can say that perhaps there would be some inner class in the interface, then the class implementing the interface will have it. 现在我们可以说接口中可能会有一些inner class ,那么实现接口的类将拥有它。 But again that will be static implicitly and will belong to the interface. 但是同样,它将隐式地是static并且将属于接口。 Therefore, all what the class will get are methods. 因此,该类将获得的全部是方法。 And don't forget just the definition and the contract which says, "the class implementing this interface must provide the implementation of all methods or declare itself abstract ". 并且不要忘了定义和约定,它说:“实现此接口的类必须提供所有方法的实现或声明自己为abstract ”。 Hence, that class will only get responsibilities and nothing much. 因此,这个班级只会承担责任而已。 But that solves our problems in a brilliant way. 但这以出色的方式解决了我们的问题。

Bottom line 底线

Therefore, we say 因此,我们说

  • There are no global variables in Java Java中没有全局变量
  • Java doesn't support multiple-inheritance, but something like that can be achieved by implementing multiple interfaces. Java不支持多重继承,但是可以通过实现多个接口来实现类似的目的。 And that really works 那真的有效
  • There is nothing pass-by-reference in Java, but references are pass-by-value Java中没有传递引用,但引用是传递值

Now I like to site few more places 现在我想在另外几个地方

  • Java does not support global, universally accessible variables. Java不支持全局通用变量。 You can get the same sorts of effects with classes that have static variables [Ref] 您可以使用具有静态变量的类获得相同的效果[Ref]
  • However, extern in ObjectiveC is not an alternative to a class-scoped static variable in Java, in fact it is more like a global variable … so use with caution. 但是,ObjectiveC中的extern Java中的类作用域的静态变量,实际上,它更像是全局变量……因此请谨慎使用。 [Ref] [参考]
  • In place of global variables as in C/C++, Java allows variables in a class to be declared static [Ref] 代替C / C ++中的全局变量,Java允许将类中的变量声明为静态[Ref]
  • Furthermore, the overuse of static members can lead to problems similar to those experienced in languages like C and C++ that support global variables and global functions. 此外,静态成员的过度使用可能导致与支持全局变量和全局函数的C和C ++语言类似的问题。 [Ref] [参考]

All these are inferring one and the same idea. 所有这些都在暗示着一个相同的想法。 Which is Java doesn't support global variables. Java不支持全局变量。

Hell, I wrote that much. 地狱,我写了那么多。 Sorry folks. 抱歉

Performance doesn't matter. 性能无所谓。 You want it as easy to read as possible. 您希望它尽可能容易阅读。

I would do 2 as much as you can. 我会尽你所能。 When you really need constants and statics, make constants and statics. 当您确实需要常量和静态变量时,请创建常量和静态变量。

For example, a null safe trim makes a good static method. 例如,空安全修整是一种很好的静态方法。 New upping a StringTrimmer is silly. 新增加StringTrimmer很愚蠢。 Putting if null then x else z in 1000 others is silly. 如果将null放到1000个其他的x else z中,那是很傻的。

I think this was settled back in 1956 and 1958, when people invented Lisp and ALGOL58 and pondered about modularity, referential transparency, and sound code structure as means to tackle impenetrable spaghetti code that rely on global variables (and who tend to exhibit the software equivalent of the Heisenberg uncertainty principle.) 我认为这可以回溯到1956年和1958年,当时人们发明了Lisp和ALGOL58,并开始思考模块化,参照透明性和健全的代码结构,以解决依赖于全局变量(并且倾向于展示与软件等效的方法)的难以理解的意大利面条式代码。 (海森堡不确定性原理)。

I mean seriously, this is 2011 and we still wonder about whether to use global variables over encapsulated fields or parameter passing for quote-n-quote efficiency . 我的意思是认真的说,这是2011年,我们仍然想知道是否在封装字段上使用全局变量或使用参数传递来提高quote-n-quote的效率 I mean, seriously. 我的意思是,认真。

I may sound arrogant (so be it), but I'll say this: 我可能听起来很自大(就是这样),但是我会这样说:

I can understand some spaces where you have to make some sort of global variable trade-offs (.ie. very resource constrained embedded platforms, for example). 我可以理解一些必须进行全局变量权衡的空间(例如,资源非常有限的嵌入式平台)。 I can understand if a person that is just starting in CS (say a freshman) asks this. 我能理解一个刚开始使用CS的人(比如大一新生)是否会问这个问题。

But if someone beyond freshman level (let alone someone that does coding for a living and not coding in the most resource barren of environments) asks or even remotely thinks about this as an acceptable thing to do should seriously reconsider going back to the basics (or reconsider this profession - we have too much craptacular code already.) 但是,如果某人超出了新生的水平(更不用说是为生活编写代码而不是在资源最贫乏的环境中编写代码的人)问或什至遥遥地认为这是可以接受的事情,则应该认真地重新考虑基础知识(或重新考虑这个专业-我们已经有了太多奇特的代码。)

Short and concise answer: No, it makes no sense. 简短的回答:不,这没有任何意义。 There are no noticeable games. 没有值得注意的游戏。 It is not worth it. 这是不值得的。 It leads to craptacular code. 它导致奇特的代码。 And all of these have been known for 50 years now. 所有这些都已经有50年了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM