8

有人可以解释以下情况之间的区别以及我们将在哪里使用每种情况吗?谢谢大家

class A{
  static public void methodA()
}

static class B{
  static public void methodB()
}

static class C{
  public void methodC()
}

编辑:大家好,感谢您的回答。我可能还不够清楚。我知道类 B 和 C 不能声明为静态,除非它们是内部类。我在你的回答中请假设它们是内部类。我想知道何时将它们声明为静态,甚至何时将它们的方法声明为静态。我知道非静态类中的静态方法意味着您可以从任何地方调用它,并且通常执行并非特定于对象的一般操作。但是你为什么要声明静态类呢?在您重新阅读我的编辑并接受最具解释性的答案后,我将再次检查您的答案

4

4 回答 4

4

static修饰符用于声明静态字段或类变量

它们与类相关联,而不是与任何对象相关联。类的每个实例共享一个类变量,该变量位于内存中的一个固定位置。任何对象都可以更改类变量的值,但也可以在不创建类实例的情况下操作类变量。

来源:“了解实例和类成员”

另请注意,Java 支持静态变量和方法。因此,这样一来,您的第一个类将正确编译,而其他两个将失败。

举个例子:

class A{
    public static int STATIC_VALUE = 1; // is a valid static variable

    public static void method1(){ 
        //is a valid static method
    }

    /**
    * Is a valid static inner class
    */
    static class innerClassB{

    }
}

但是你为什么要声明静态类呢?

有一些原因可以说明为什么要这样做。例如,来自这个Java 教程

静态嵌套类与其外部类(和其他类)的实例成员交互,就像任何其他顶级类一样。实际上,静态嵌套类在行为上是一个顶级类,为了方便打包,它已经嵌套在另一个顶级类中。

这方面的一个很好的例子是static class Entry<K,V> implements Map.Entry<K,V>在像HashMap类这样的地方使用。

Entry 类的存在与 HashMap 如何存储/检索存储为其内容的键/值对的功能密切相关。如您所见,Entry 类仅向 HashMap 实现提供功能,即使它在行为上等同于顶级类。因此,将其打包为 HashMap 定义本身的一部分是有意义的。

private static class Entry<E>您可以在 LinkedList 实现中 找到类似的用法。

我能想到的另一个原因是白盒测试的一种方式。由于内部静态类可以访问外部类的私有和受保护静态变量/方法,因此您可以很好地使用它来测试外部类的内部状态。有些人可能会认为这很脏,但有时它可能很有用

在我看来,静态内部类主要是为了方便,并且通常基于您的设计原则。

于 2012-09-30T04:19:35.763 回答
1

A 类将有一个静态类级方法。它不会与任何类实例相关,它会

B 类和 C 类是非法的,不能将类定义为静态的。

编辑:就像HFoE所说,如果B或C是内部类,它们会起作用。在这种情况下,他们将无法访问外部类的实例属性。

于 2012-09-30T04:16:17.983 回答
1

这里基本上有两种用途static

  • staticon a class 只能用于嵌套类;即在其他类中声明的命名类。这意味着嵌套类的实例没有封闭外部类的父实例。

  • staticon a method 表示该方法不适用于包含类的实例;即方法的主体不能引用this


这意味着您的声明BC是无效的,因为它们没有在外部类中声明。

(另一个答案说顶级类是隐式静态的。从某种意义上说,这是真的,但另一种看待它的方式static是对顶级类毫无意义。无论哪种方式,Java 语言都不允许您声明顶级类为static。这是一个编译错误。)

于 2012-09-30T04:19:25.830 回答
0

所有的外层类都是静态的,但不能为它们提及静态保留字,因此 B 和 C 作为外层类是非法的。

但所有情况都是有效的内部类。在这种情况下,A 是成员内部类,但 B 和 C 是静态内部类(相当于普通类)。

A 和 B 包含一个静态方法,但 C 没有。

于 2012-09-30T04:20:08.637 回答