为什么你不能在Java中将类声明为静态?

Why are you not able to declare a class as static in Java?

为什么你不能在Java中声明一个类作为静态?


只有嵌套类可以是静态的。通过这样做,您可以使用嵌套类,而不必具有外部类的实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class OuterClass{
    public static class StaticNestedClass{
    }

    public class InnerClass{
    }

    public InnerClass getAnInnerClass(){
        return new InnerClass();
    }

    //This method doesn't work
    public static InnerClass getAnInnerClassStatically(){
        return new InnerClass();
    }
}

class OtherClass{
    //Use of a static nested class:
    private OuterClass.StaticNestedClass staticNestedClass = new OuterClass.StaticNestedClass();

    //Doesn't work
    private OuterClass.InnerClass innerClass = new OuterClass.InnerClass();

    //Use of an inner class:
    private OuterClass outerclass= new OuterClass();
    private OuterClass.InnerClass innerClass2 = outerclass.getAnInnerClass();
    private OuterClass.InnerClass innerClass3 = outerclass.new InnerClass();
}

资料来源:

  • 关于嵌套类的Oracle教程

关于同一主题:

  • JAVA:静态与非静态内部类
  • Java内部类和静态嵌套类


默认情况下,顶级类是静态的。默认情况下,内部类是非静态的。您可以通过显式地将内部类标记为静态来更改其默认值。顶级类由于是顶级的,因此不能具有非静态语义,因为没有可引用的父类。因此,无法更改顶级类的默认值。


所以,我要迟到了,但这是我的两分,哲学上增加了科林·赫伯特的回答。

在较高的层次上,您的问题处理对象和类型之间的差异。虽然有许多汽车(对象),但只有一个汽车类(类型)。将某个东西声明为静态的意味着您正在"类型"空间中操作。只有一个。顶级class关键字已经在"type"空间中定义了一个类型。因此,"公共静态类汽车"是多余的。


具有私有构造函数的类是静态的。

像这样声明您的类:

1
2
3
4
5
6
7
8
9
public class eOAuth {

    private eOAuth(){}

    public final static int    ECodeOauthInvalidGrant = 0x1;
    public final static int    ECodeOauthUnknown       = 0x10;
    public static GetSomeStuff(){}

}

您可以在不初始化的情况下使用:

1
2
3
if (value == eOAuth.ECodeOauthInvalidGrant)
    eOAuth.GetSomeStuff();
...


您可以通过声明不带实例的枚举类型来创建实用程序类(不能创建实例)。也就是说,您具体地声明没有实例。

1
2
3
public enum MyUtilities {;
   public static void myMethod();
}


当然可以,但仅限于inner->nested classes。在这里,这意味着嵌套类的实例不需要外部类的封闭实例。

但是对于顶级的类,语言设计人员无法想到与关键字有关的任何有用的东西,因此这是不允许的。


1
2
3
public class Outer {
   public static class Inner {}
}

…它可以声明为静态的-只要它是成员类。

来自JLS:

Member classes may be static, in which case they have no access to the instance variables of the surrounding class; or they may be inner classes (§8.1.3).

这里:

The static keyword may modify the declaration of a member type C within the body of a non-inner class T. Its effect is to declare that C is not an inner class. Just as a static method of T has no current instance of T in its body, C also has no current instance of T, nor does it have any lexically enclosing instances.

静态关键字对于顶级类没有任何意义,因为顶级类没有封闭类型。


如上所述,类不能是静态的,除非它是另一个类的成员。

如果要设计一个"不能有多个实例"的类,您可能需要研究"单例"设计模式。

这里是初学者单打信息。

Caveat:

If you are thinking of using the
singleton pattern, resist with all
your might. It is one of the easiest
DesignPatterns to understand, probably
the most popular, and definitely the
most abused.
(source: JavaRanch as linked above)


除了Java如何定义静态内部类外,还有一个静态类的定义,如CyWord Word(1)。静态类是一个只有静态方法(函数)的类,它旨在支持过程编程。此类类并不是真正的类,因为类的用户只对辅助函数感兴趣,而不关心创建类的实例。虽然C类中支持静态类,但Java中不存在这样的直接支持。但是,您可以使用枚举来模仿Java中的C类静态类,这样用户就永远不能创建给定类的实例(甚至使用反射)(2):

1
2
3
4
5
6
7
8
public enum StaticClass2 {
    // Empty enum trick to avoid instance creation
    ; // this semi-colon is important

    public static boolean isEmpty(final String s) {
        return s == null || s.isEmpty();
    }
}

我们在Java中编码的所有东西都进入一个类。每当我们运行一个类时,jvm实例化一个对象。JVM可以创建许多对象,根据定义,静态意味着您对所有对象都有相同的复制集。

因此,如果Java在运行程序时允许顶级类是静态的,那么它将创建一个对象,并将其重写到同一个内存位置。

如果每次运行对象时都要替换它,那么创建它的意义是什么?

这就是Java摆脱顶级类静态的原因。

可能还有更具体的原因,但这对我来说是合乎逻辑的。


唯一可以是静态的类是内部类。以下代码工作正常:

1
2
3
4
public class whatever {
    static class innerclass {
    }
}

静态内部类的要点是它们没有对外部类对象的引用。


我们可以在Eclipse中查看PlatformUI中静态方法和私有构造函数的类,它们本身是最终的。

1
2
3
4
5
public final class <class name>
{
   //static constants
   //static memebers
}

我想这可能和喝一杯咖啡一样容易!.看看这个。定义类时不显式使用静态关键字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class StaticClass {

    static private int me = 3;
    public static void printHelloWorld() {
       System.out.println("Hello World");
    }



    public static void main(String[] args) {
        StaticClass.printHelloWorld();
        System.out.println(StaticClass.me);
    }
}

这不是静态类的定义吗?我们只使用绑定到类的函数。注意,在这种情况下,我们可以使用嵌套中的另一个类。看看这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class StaticClass1 {

    public static int yum = 4;

    static void  printHowAreYou() {
        System.out.println("How are you?");
    }
}

public class StaticClass {

    static int me = 3;
    public static void printHelloWorld() {
       System.out.println("Hello World");
       StaticClass1.printHowAreYou();
       System.out.println(StaticClass1.yum);
    }



    public static void main(String[] args) {
        StaticClass.printHelloWorld();
        System.out.println(StaticClass.me);
    }
}


如果使用静态类的好处不是实例化一个对象并使用一个方法,那么只需将该类声明为公共的,而将该方法声明为静态的。