472

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

4

14 回答 14

485

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

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();
}

资料来源:

在同一主题上:

于 2010-08-27T12:36:12.843 回答
43

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

于 2013-08-18T21:12:12.220 回答
37

所以,我来晚了,但这是我的两分钱 - 从哲学上补充科林赫伯特的答案。

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

于 2013-06-27T21:18:18.943 回答
29

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

像这样声明你的类:

public class eOAuth {

    private eOAuth(){}

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

}

您无需初始化即可使用:

if (value == eOAuth.ECodeOauthInvalidGrant)
    eOAuth.GetSomeStuff();
...
于 2012-05-31T16:28:00.157 回答
13

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

但是对于顶级类,语言设计者想不出关键字有什么用,所以是不允许的。

于 2010-08-27T12:36:11.380 回答
13

您可以通过声明没有实例的枚举类型来创建实用程序类(不能创建实例)。即您明确声明没有实例。

public enum MyUtilities {;
   public static void myMethod();
}
于 2010-08-27T22:13:30.760 回答
9
public class Outer {
   public static class Inner {}
}

...它可以被声明为静态的——只要它是一个成员类。

来自 JLS:

成员类可能是静态的,在这种情况下它们无法访问周围类的实例变量;或者它们可能是内部类(§8.1.3)。

和这里:

static 关键字可以在非内部类 T 的主体内修改成员类型 C 的声明。它的作用是声明 C 不是内部类。正如 T 的静态方法在其主体中没有 T 的当前实例一样,C 也没有 T 的当前实例,也没有任何词法封闭实例。

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

于 2010-08-27T12:36:07.447 回答
6

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

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

初学者单身信息在这里

警告:

如果您正在考虑使用单例模式,请全力抵抗。它是最容易理解的设计模式之一,可能是最流行的,而且绝对是被滥用最多的。 (来源:上面链接的 JavaRanch)

于 2010-08-27T12:51:22.760 回答
4

除了 Java 如何定义静态内部类之外,根据 C# 世界[1] ,还有另一种静态类的定义。静态类是只有静态方法(函数)的类,它旨在支持过程编程。这样的类并不是真正的类,因为类的用户只对辅助函数感兴趣,而不对创建类的实例感兴趣。虽然 C# 支持静态类,但 Java 中不存在这种直接支持。但是,您可以使用枚举来模仿 Java 中的 C# 静态类,以便用户永远无法创建给定类的实例(即使使用反射)[2]

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();
    }
}
于 2013-05-13T21:36:09.303 回答
3

我们用java编写的所有代码都进入了一个类。每当我们运行一个类时,JVM 都会实例化一个对象。JVM 可以创建多个对象,根据定义,静态意味着您对所有对象拥有相同的副本集。

因此,如果 Java 在您运行程序时允许顶级类是静态的,它会创建一个对象并继续覆盖相同的内存位置。

如果您只是在每次运行时都替换对象,那么创建它的意义何在?

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

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

于 2013-08-18T21:03:07.743 回答
2

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

public class whatever {
    static class innerclass {
    }
}

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

于 2013-08-02T09:01:37.283 回答
1

我认为这就像喝一杯咖啡一样容易!看看这个。我们在定义类时不显式使用 static 关键字。

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);
    }
}

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

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);
    }
}
于 2012-05-17T14:42:04.360 回答
1

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

public final class <class name>
{
   //static constants
   //static memebers
}
于 2012-11-28T06:52:56.100 回答
0

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

于 2013-01-31T10:52:41.037 回答