【问题标题】:Static Methods or Not? Global variables?静态方法与否?全局变量?
【发布时间】:2011-05-12 10:40:32
【问题描述】:

我想知道哪种方式更有效率。

  1. 没有全局变量,通过参数传递变量,所有方法都是静态的

  2. 没有全局变量,只有 main 方法 static 并在 main 中创建类对象来访问方法

  3. 只使用全局变量,只有 main 方法 static 并在 main 中创建类对象来访问方法

我目前正在使用方法 3,但我想知道哪种方法更有效。这个类不会被它之外的任何其他类使用,它几乎是独立的。

我的代码结构示例:

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() {...}
}

【问题讨论】:

  • 简短回答:没关系。更长的答案:它真的没关系。可读性、可靠性和可维护性是目标,而不是微优化。此外,Java 没有全局变量。您的示例说明了实例变量。如果您仍然想知道,请设置测试并计时。
  • +1 表示“测试它”,乔纳森。阅读和重新阅读人们提出的问题本可以在大约十分钟的工作中得到明确回答的问题是令人厌烦的。

标签: java oop static


【解决方案1】:
  • 没有阶级是孤岛。
  • 没有银子弹,至少其在编程非常真实的。 LI>
  • 过早的优化是万恶之源。
  • 在 Java 中我们没有全局变量。我们只有类变量,实例变量和方法变量。

[编辑]

我试图在这里解释我的最后一点。实际上,至此讨论中,将会-在cmets下面,实际交 P>

首先看看这个,an SO thread of C#。也有人提出同样的建议,那就是,

那么,我们开始吧。

反驳:类是全局作用域的,因此所有类变量都是全局作用域的。因此应该称为全局。

counter-retort:并非所有的类都是全局范围的。一个类可以是package-private。因此,static变量都不会有外部可见的包。因此,不应将其称为全局。此外,类可以嵌套,因此也可以是 private,当然也可以有一些 static 变量,但这些变量不会被称为全局变量。

反驳: public 类是全局范围的,因此所有类变量都是全局范围的。

反驳:不完全是。我想在这里,但对一个变量的水平移动之前的说法。不管类本身是否为public。其中的变量可以是protectedpackage-privateprivate。因此,static 变量在这种情况下将不是全局变量。

现在,如果您想在public static 类中调用public static 变量,作为全局变量,请以任何方式调用它。但是请考虑这一点,当您创建一个新的ClassLoader(作为引导程序ClassLoader 的子级)并加载一个您已经加载的类时。然后这会产生一个“非常新的类副本”——完成它自己的一组新的statics。确实非常“非全球性”。但是,我们在 Java 中不使用全局这个词,因为它往往会使事情变得混乱,然后我们需要提供大量的解释来让一切变得清晰。人们很喜欢用static 变量来解释Java 中global 变量的特性。这没有问题。如果您有任何其他语言的问题/代码并且使用全局变量并且您需要将该代码转换为 Java,那么您很可能会使用 static 变量作为替代。

我喜欢在这里呈现几个示例

  1. 当我开始使用Java时,讲师喜欢解释传递对象类型变量和原始变量的区别。他们经常使用术语对象pass-by-reference,而原语是pass-by-value。学生们觉得这个解释很混乱。因此,我们提出了 Java 中的所有内容都是按值传递的概念。我们解释了对象引用是按值传递的。它变得更加清晰和简单。

  2. 同样,有些语言支持多重继承。但是 Java 没有,同样可以说。但是人们倾向于使用interfaces 来解释该功能。他们以一流的解释实现多个接口,并称之为多重继承。这完全没问题。但是,什么阶级,实际上,通过继承多个接口接收。坦白说,没什么。为什么?

    。因为接口中的所有变量都隐含为publicfinalstatic,这显然意味着它们属于该类并且任何人都可以访问它们。现在我们可以说接口中可能会有一些inner class,那么实现该接口的类就会有它。但同样,这将是static含蓄,将属于接口。因此,该类将获得的所有内容都是方法。并且不要忘记定义和约定,“实现此接口的类必须提供所有方法的实现或声明自己abstract”。因此,该班级只会承担责任,而不会承担太多责任。但这以绝妙的方式解决了我们的问题。

底线

因此,我们说

  • Java 中没有全局变量
  • Java 不支持多重继承,但类似的事情可以通过实现多个接口来实现。这确实有效
  • 没有什么通按引用在Java中,但引用是通过按值 LI>

现在我想多选几个地方

  • Java 不支持全局、普遍可访问的变量。你可以得到同样类型的效果与具有静态变量@ 987654324类@
  • 然而,ObjectiveC 中的extern 并不是Java 中类范围静态变量的替代品,实际上它更像是一个全局变量……所以请谨慎使用。 [Ref]
  • 代替 C/C++ 中的全局变量,Java 允许将类中的变量声明为静态 [Ref]
  • 此外,静态成员的过度使用会导致与支持全局变量和全局函数的 C 和 C++ 等语言中遇到的问题类似的问题。 [Ref]

所有这些都在推断同一个想法。哪个是Java不支持全局变量。

哎呀,我写了这么多。对不起各位。

【讨论】:

  • 我不同意你的最后一个要点 - 类是全局范围的,因此所有类变量都是全局范围的。
  • @gustafc:顺便说一句,可以说,类变量不是全局变量。那么你可以尝试看看它以这种方式,这是我们尽量避免任何混淆的方式。在某些语言中,通常不使用术语“静态变量”,因为“本地”和“全局”足以涵盖所有可能性。但在 Java 中并非如此,因此我们完全避免使用它。
  • @gustafc:至少对于来自不同语言的一些人来说,全局意味着一个变量,它也在任何类之外,因此全局是一个真正的意义。我希望你明白我的意思。您可以尝试搜索“Java 中的全局变量”,您肯定会遇到相同的结果。
  • @gustafc - 当你创建一个新的类加载器(作为引导类加载器的子类)并加载一个你已经加载的类时,你知道你在 Java 中得到了什么吗?答:类的新副本......完全有自己的一套新的静力学。非常联合国全球性。
  • @StephenC - 另一方面,如果你创建一个“全局变量类”并且所有使用它的类都由同一个类加载器或它的子类加载 - 你肯定 全局变量。 (很遗憾,许多应用为此目的使用系统属性。它们真的很可爱——它们不仅是全局的,而且也不是类型安全的。)
【解决方案2】:

我认为这在 1956 年和 1958 年得到了解决,当时人们发明了 Lisp 和 ALGOL58,并考虑将 模块化、引用透明性和健全的代码 结构作为解决问题的手段依赖于全局变量的难以理解的意大利面条代码(并且往往表现出与海森堡不确定性原理等效的软件。)

我的意思是,这是 2011 年,我们仍然想知道是否在封装字段上使用全局变量或参数传递来实现 quote-n-quote 效率。我的意思是,说真的。

我可能听起来很自大(就这样吧),但我会这样说:

我可以理解 一些 空间,您必须在其中进行某种全局变量权衡(例如,资源非常受限的嵌入式平台)。如果一个刚开始接触 CS 的人(比如大一新生)问这个问题,我可以理解。

但是,如果超出大一水平的人(更不用说以编码为生,而不是在资源最贫瘠的环境中编码的人)提出要求,甚至远程认为这是可以接受的事情,那么应该认真重新考虑回到基础知识(或者重新考虑这个职业——我们已经有太多乱七八糟的代码了。)

简短的回答:不,这没有意义。没有引人注目的游戏。这是不值得的。它会导致杂乱无章的代码。所有这些都已为人所知 50 年了。

【讨论】:

    【解决方案3】:

    性能无关紧要。您希望它尽可能易于阅读。

    我会尽可能多地做 2。当你真的需要常量和静态时,制作常量和静态。

    例如,null 安全修剪是一个很好的静态方法。新增加 StringTrimmer 是愚蠢的。将 if null then x else z 放在其他 1000 个中是愚蠢的。

    【讨论】:

    • 我觉得不加限定就说“性能无关紧要”是相当愚蠢的。是的,大多数微优化可能不值得努力,但时不时地。知道这两种情况的区别是有用的,而不是仅仅说没关系。
    猜你喜欢
    • 1970-01-01
    • 2015-06-12
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-28
    • 1970-01-01
    • 2023-03-22
    相关资源
    最近更新 更多