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

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

334423 次浏览
public class Outer {
public static class Inner {}
}

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

来自JLS:

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

在这里:

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

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

当然可以,但只能内心的嵌套类。在这里,它意味着嵌套类的实例不需要外部类的封闭实例。

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

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

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

来源:

关于同一话题:

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

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

初学者单例信息在这里

警告:

如果你正在考虑使用 单例模式,抵制与所有 你的可能。这是最简单的方法之一 设计模式来理解,可能 最受欢迎的,绝对是 大多数滥用。 (来源:JavaRanch如上链接)

您可以通过声明一个没有实例的enum类型来创建一个实用程序类(它不能创建实例)。也就是说,你明确地声明没有实例。

public enum MyUtilities {;
public static void myMethod();
}
我认为这可能就像喝一杯咖啡一样简单! 看看这个。 定义类时不显式使用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);
}
}

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

像这样声明你的类:

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

你可以在Eclipse中的PlatformUI中找到一个带有静态方法和自身为final的私有构造函数的类。

public final class <class name>
{
//static constants
//static memebers
}

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

除了Java如何定义静态内部类之外,还有另一个根据c# world[1]定义的静态类。静态类是只有静态方法(函数)的类,它意味着支持过程式编程。这样的类并不是真正的类,因为类的用户只对helper函数感兴趣,而对创建类的实例不感兴趣。虽然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();
}
}

所以,我来晚了,但这是我的两种观点——哲学上补充科林·赫伯特的答案。

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

唯一可以是静态的类是内部类。下面的代码工作得很好:

public class whatever {
static class innerclass {
}
}

静态内部类的意义在于它们没有外部类对象的引用。

我们在java中编写的所有代码都包含在一个类中。每当我们运行一个类时,JVM都会实例化一个对象。JVM可以创建许多对象,根据定义,静态意味着对所有对象都有相同的复制集。

所以,如果Java允许顶级类是静态的,无论何时你运行一个程序,它都会创建一个对象,并保持在相同的内存位置上重写。

如果你只是在每次运行时替换对象,那么创建它有什么意义呢?

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

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

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