Java中的静态类

Kra*_*ken 906 java static-classes

static classjava中有类似的东西吗?

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

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

什么是静态类有用?

Pau*_*sik 820

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

  • 声明你的类final- 防止扩展类,因为扩展静态类是没有意义的
  • 创建构造函数private- 防止客户端代码实例化,因为实例化静态类是没有意义的
  • 创建类的所有成员和函数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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 只有`static`方法的类`Foo`与`static class Foo`不同 (34认同)
  • 这个答案可能解决了OP的意思,但它(目前)并没有解释Java静态类,所以根本不回答这个问题!对于那些试图弄清楚静态类在Java中意味着什么的人来说,这是非常糟糕的. (29认同)
  • @Evorlor:如果一个类被声明为final,那么它的方法将自动(有效)为final.这是因为最终的类不能被子类化,因此它的方法不能被覆盖(即,实际上是最终的).http://docs.oracle.com/javase/tutorial/java/IandI/final.html (12认同)
  • @JBoy:Java中存在"静态类"这样的问题,这就是问题所在,但这个答案根本没有解释.相反,它解释了如何在Java中模拟答案所谓的"静态类" - 但它不是*Java中的"静态类"!(也许它在其他一些语言中被称为"静态类",但是来到这里学习Java静态类的人会被误导和混淆.) (12认同)
  • 你应该明确提到私有MyStaticClass(){//私有构造函数myStaticMember = 1; 因为不会调用构造函数,所以根本没有任何影响.但这不是重点.我仍然对Java中静态内部类的实用性及其实用性或附加值感到困惑. (4认同)
  • 我不明白为什么你的私有构造函数有一个主体......它永远不会被调用。为什么不初始化静态字段? (2认同)
  • @Tom 但这对来这里了解非嵌套静态类的人来说非常有用;) (2认同)

Jon*_*eet 308

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

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

在Java中没有顶级静态类.

  • @Geek:你看过我的回答了吗?仔细阅读第二句话.为什么你*不希望能够拥有静态类的实例方法?毕竟,您可以创建它们的实例. (18认同)
  • @Geek:是的,这完全是允许的.基本上,您对实用类的"理解"是不正确的.这不是Java中的静态类的意思. (16认同)
  • 在Java中为什么静态嵌套类允许实例方法?在这样的类中使用实例方法有什么用? (12认同)
  • @Geek:是的.正如我在我的回答中所写:"静态嵌套类只是一个不隐式地引用外部类的实例的类." (12认同)
  • @KhurramAli:你的意思*隐含*?鉴于在声明它们时不使用关键字`static`,它们肯定不是*显式*静态的.它们是隐式的,因为你不需要引用任何其他东西来构造它.就个人而言,无论如何我发现静态/非静态术语对于嵌套类来说有点奇怪...我认为谈论行为是什么会更简单. (5认同)
  • 那么当我们说Java中的一个类是`static`时,它对那个类有什么看法呢?它是否说该类的实例可以独立存在并且不需要封闭类实例的帮助来实例化它自己? (2认同)
  • @ H2ONaCl可以实例化静态和非静态嵌套类.我不知道一个不同的关键字是否会更好 - 或者只是不让内部类具有对外部类的实例的隐式引用会更好.我不会错过C#. (2认同)

ami*_*mit 147

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

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

代码示例:

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(); 
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 那么我们是否可以说我们可以使用内部静态类来实例化它们而不需要将它们公开? (2认同)
  • @moldovean 静态/非静态与可见性正交。您可以使用静态或非静态的任何类型的可见性。关键是,为了创建内部类,您是否需要一个封闭类的实例? (2认同)

Bit*_*map 98

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

例:

public class A
{

 public static class B
 {
 }
}
Run Code Online (Sandbox Code Playgroud)

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

B b = new B();
Run Code Online (Sandbox Code Playgroud)

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

A a= new A();
B b = a.new B();
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您可以定期实例化非静态类,例如`B b = new B();`如果您尝试从类'A`本身实例化它. (7认同)
  • 这个解释比其他解释清楚得多. (4认同)

Ram*_*h-X 32

当一个成员class被宣布为static......时会发生什么?可以在不实例化的情况下访问成员class.因此,制作外类(顶级类)static没有任何意义.因此不允许这样做.

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

public class A {
    public static class B {

    }
}
Run Code Online (Sandbox Code Playgroud)

现在,在不同的类中C,B可以在不创建类实例的情况下访问类A.

public class C {
    A.B ab = new A.B();
}
Run Code Online (Sandbox Code Playgroud)

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

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

public class C {
    A a = new A();
    A.B ab = a. new B();
}
Run Code Online (Sandbox Code Playgroud)

但是我们不能staticnon-static内部类中拥有成员.

  • 与其他语言不同,`static`在java中只有一个含义.如果某个类中的某个东西是"静态",则意味着可以在不实例化该类的情况下访问该东西.它没有说有关创建实例的内容. (3认同)

Ben*_*ber 12

看来这是谷歌"静态类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() { ... }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 实现Singleton的好方法.不幸的是,问题不在于单身人士,而在于静态课程 (5认同)
  • AC# 静态类不是单例。Singleton 实例是一个对象并且可以实现一个接口,这意味着它可以参与依赖注入并且可以被模拟。AC#静态类不能实现接口,也不能以任何方式注入,更接近一堆C函数,当然也允许扩展方法。 (2认同)

roo*_*ler 12

Java中的类可以是静态的吗?

答案是肯定的,我们可以在java中使用静态类.在java中,我们有静态实例变量以及静态方法静态块.类也可以在Java中变为静态.

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

静态嵌套类与非静态嵌套类

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

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

https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html


Sak*_*ket 8

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

  • [“静态内部”是一个矛盾的术语。](https://docs.oracle.com/javase/specs/jls/se12/html/jls-8.html#jls-8.1.3) (2认同)

sai*_*and 6

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

顶级类:一个ja​​va项目在每个java源文件中可以包含多个顶级类,其中一个类以文件名命名。顶级类前面只允许使用三个选项或关键字: public、abstract 和 Final

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

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

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

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