it-swarm.cn

Java中的静态类

Java中有static class之类的东西吗?

这类课的意义是什么。静态类的所有方法都需要static吗?

是否需要反过来说,如果一个类包含所有静态方法,那么该类是否也应该是静态的?

什么是静态类有用?

863
Kraken

Java有静态嵌套类,但听起来你正在寻找一个顶级静态类。 Java没有办法让顶级类静态,但你可以像这样模拟一个静态类:

  • 声明你的类final - 防止扩展类,因为扩展静态类是没有意义的
  • 使构造函数private - 防止客户端代码实例化,因为实例化静态类是没有意义的
  • Make all 类的成员和函数static - 由于无法实例化类,因此无法调用实例方法或访问实例字段
  • 请注意,编译器不会阻止您声明实例(非静态)成员。只有在尝试调用实例成员时才会显示该问题

根据上述建议的简单示例:

public class TestMyStaticClass {
     public static void main(String []args){
        MyStaticClass.setMyStaticMember(5);
        System.out.println("Static value: " + MyStaticClass.getMyStaticMember());
        System.out.println("Value squared: " + MyStaticClass.squareMyStaticMember());
        // MyStaticClass x = new MyStaticClass(); // results in compile time error
     }
}

// A top-level Java class mimicking static class behavior
public final class MyStaticClass {
    private MyStaticClass () { // private constructor
        myStaticMember = 1;
    }
    private static int myStaticMember;
    public static void setMyStaticMember(int val) {
        myStaticMember = val;
    }
    public static int getMyStaticMember() {
        return myStaticMember;
    }
    public static int squareMyStaticMember() {
        return myStaticMember * myStaticMember;
    }
}

静态类有什么用? 静态类的一个好用途是定义一次性,实用程序和/或库类,其中实例化没有意义。一个很好的例子是Math类,它包含一些数学常量,如PI和E,只是提供数学计算。在这种情况下要求实例化将是不必要和令人困惑的。请参阅 Math class和 源代码 。请注意它是final并且其所有成员都是static。如果Java允许将顶级类声明为static,那么Math类确实是静态的。

790
Paul Sasik

好吧,Java有“静态嵌套类”,但它们与C#的静态类完全不同,如果那是你来自的地方。静态嵌套类只是一个不隐式引用外部类实例的类。

静态嵌套类可以包含实例方法和静态方法。

在Java中没有顶级静态类。

296
Jon Skeet

有一个静态 嵌套类 ,这个[静态嵌套]类不需要封闭类的实例,以便自己实例化。

这些类[静态嵌套的]只能访问封闭类的静态成员[因为它没有对封闭类的实例的任何引用...]

代码示例:

public class Test { 
  class A { } 
  static class B { }
  public static void main(String[] args) { 
    /*will fail - compilation error, you need an instance of Test to instantiate A*/
    A a = new A(); 
    /*will compile successfully, not instance of Test is needed to instantiate B */
    B b = new B(); 
  }
}
143
amit

是的,Java中有一个静态嵌套类。当你声明一个嵌套类static时,它会自动成为一个独立的类,可以实例化它而不必实例化它所属的外部类。

示例:

public class A
{

 public static class B
 {
 }
}

因为class B被声明为static,所以您可以显式实例化为:

B b = new B();

请注意,如果class B未声明为静态以使其独立,则实例对象调用将如下所示:

A a= new A();
B b = a.new B();
92
Bitmap

class中的成员声明为static ..时发生了什么?可以在不实例化class的情况下访问成员。因此,使外部类(顶级类)static没有意义。因此不允许这样做。

但是您可以将内部类设置为静态(因为它是顶级类的成员)。然后可以在不实例化顶级类的情况下访问该类。请考虑以下示例。

public class A {
    public static class B {

    }
}

现在,在另一个类C中,可以访问类B而无需创建类A的实例。

public class C {
    A.B ab = new A.B();
}

static类也可以有non-static成员。只有该类获得静态。

但是如果从类static中删除了B关键字,则在不创建A的实例的情况下无法直接访问它。

public class C {
    A a = new A();
    A.B ab = a. new B();
}

但是我们不能在non-static内部类中包含static成员。

31
Ramesh-X

一个类可以在Java中是静态的吗?

答案是 _是_ ,我们可以在Java中使用静态类。在Java中,我们有静态实例变量以及静态方法以及静态块。类也可以在Java中变为静态。

在Java中,我们不能使顶级(外部)类静态。 只有嵌套类可以是静态的。

静态嵌套类vs非静态嵌套类

1)嵌套静态类不需要引用外部类,但非静态嵌套类或内部类需要外部类引用。

2)内部类(或非静态嵌套类)可以访问外部类的静态和非静态成员。静态类无法访问外部类的非静态成员。它只能访问外部类的静态成员。

https://docs.Oracle.com/javase/tutorial/Java/javaOO/nested.html

12
roottraveller

看来这是谷歌“静态类Java”的最佳结果,最好的答案不在这里,我想我会添加它。我正在将OP的问题解释为关于C#中的静态类,它们在Java世界中被称为单例。对于那些不知道的人,在C#中,“static”关键字可以应用于类声明,这意味着结果类永远不能被实例化。

摘自Joshua Bloch的“Effective Java - Second Edition”(被广泛认为是最好的Java风格指南之一):

从版本1.5开始,有第三种方法来实现单例。只需使用一个元素创建一个枚举类型:

// Enum singleton - the preferred approach
public enum Elvis {
    INSTANCE;
    public void leaveTheBuilding() { ... }
}

这种方法在功能上等同于公共字段方法,除了它更简洁,免费提供序列化机制,并提供防止多实例化的铁定保证,即使面对复杂的序列化或反射攻击。虽然这种方法尚未被广泛采用,但 单元素枚举类型是实现单例的最佳方法。 (重点作者)

布洛赫,约书亚(2008-05-08)。有效的Java(Java系列)(p.18)。皮尔逊教育。

我认为实施和理由是非常自我解释的。

12
Bennet Huber

外类不能是静态的,但嵌套/内部类可以是。这基本上可以帮助您使用嵌套/内部类而无需创建外部类的实例。

9
Saket

简单来说,Java支持将类声明为仅针对内部类而非针对顶级类的静态。

顶级类: Java项目可以在每个Java源文件中包含多个顶级类,其中一个类以文件名命名。顶级类前面只允许三个选项或关键字, public,abstract和final

内部类: 在顶级类中的类称为内部类,这基本上是嵌套类的概念。 内部类可以是静态的 。使内部类静态化的想法是利用实例化内部类的对象而不实例化顶级类的对象。这与静态方法和变量在顶级类中的工作方式完全相同。

因此Java支持内部类级别的静态类(在嵌套类中)

Java不支持顶级类的静态类。

我希望这为基本理解Java中的静态类的问题提供了一个更简单的解决方案。

1
saichand

Java具有与类关联的静态方法(例如,Java.lang.Math只有静态方法),但类本身不是静态的。

1
duffymo