Java中的静态类

Posted

技术标签:

【中文标题】Java中的静态类【英文标题】:Static Classes In Java 【发布时间】:2011-11-21 02:37:49 【问题描述】:

java中有static class这样的东西吗?

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

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

静态类有什么用处?

【问题讨论】:

您可能对***.com/questions/3584113/java-static-class感兴趣 静态类基本上是用来将类分组在一起的。 【参考方案1】:

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;
    

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

【讨论】:

只有static方法的类Foostatic class Foo不同 @Evorlor:如果一个类被声明为final,那么它的方法自动(有效)是final。这是因为最终类不能被子类化,因此它的方法不能被覆盖(即,实际上是最终的)。 docs.oracle.com/javase/tutorial/java/IandI/final.html 这个答案可能解决了 OP 的意思,但它(目前)没有解释 Java 静态类,因此根本没有回答这个问题!这对于那些试图弄清楚静态类在 Java 中的含义的人来说是非常糟糕的。 @JBoy:Java中有“静态类”之类的东西,这就是问题所在,但是这个答案根本没有解释。相反,它解释了如何在 Java 中模拟答案所称的“静态类”——但这不是什么是 Java 中的“静态类”! (也许这就是其他一些语言中所谓的“静态类”,但是来这里学习 Java 静态类的人会被误导和混淆。) 你应该明确提到 private MyStaticClass () // 私有构造函数 myStaticMember = 1; 将没有任何效果,因为不会调用构造函数。但这不是重点。我仍然对 Java 中静态内部类的实用性及其实用性或附加值感到非常困惑。【参考方案2】:

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

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

Java 中没有***静态类。

【讨论】:

在Java中为什么静态嵌套类允许实例方法?这样的类中实例方法有什么用? @Geek:你看我的回答了吗?仔细阅读第二句。为什么您希望能够拥有静态类的实例方法?毕竟,您可以创建它们的实例。 @Geek:是的,这是完全允许的。基本上,您对静态类是实用程序类的“理解”是不正确的。这根本不是 Java 中静态类的意思。 @Geek:是的。正如我在回答中所写的那样:“静态嵌套类只是一个没有隐式引用外部类实例的类。” @KhurramAli:你的意思是隐含吗?它们肯定不是明确静态的,因为您在声明它们时不使用关键字static。它们是隐式静态的,因为您不需要引用其他任何东西来构建它们。就我个人而言,无论如何,我觉得静态/非静态术语对于嵌套类来说有点奇怪......我认为谈论行为是什么会更简单。【参考方案3】:

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

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

代码示例:

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

【讨论】:

那么我们可以说我们可以使用内部静态类来实例化它们而不需要将它们公开吗? @moldovean 我们使用内部静态类来从静态上下文(例如 main)实例化它们。我认为这与可见性无关。 @moldovean 静态/非静态与可见性正交。您可以通过静态或非静态获得任何类型的可见性。关键是,您是否需要封闭类的实例才能创建内部类?【参考方案4】:

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

示例:

public class A


 public static class B
 
 

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

B b = new B();

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

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

【讨论】:

请注意,如果您尝试从 A 类本身实例化非静态类,则可以像 B b = new B(); 一样定期实例化它。【参考方案5】:

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 成员。

【讨论】:

我们可以实例化一个静态类还是有意义? 与其他语言不同,static 在 java 中只有一个含义。如果某个类中有static,则意味着可以在不实例化该类的情况下访问该事物。它没有说明是否创建实例.. 对不起***!在这种情况下,我无法避免说谢谢 Ramesh-X!你几乎涵盖了我想知道的关于静态内部类和内部类的所有内容。 您不能“将内部类设置为静态”。这是contradiction in terms。嵌套类要么是内部的,要么是静态的。【参考方案6】:

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

答案是YES,我们可以在java中拥有静态类。在java中,我们有静态实例变量以及静态方法静态块。类也可以在 Java 中设为静态。

在 java 中,我们不能将***(外部)类设为静态。 只有嵌套类可以是静态的。

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

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

2) 内部类(或非静态嵌套类)可以同时访问静态 和 Outer 类的非静态成员。静态类不能访问 Outer 类的非静态成员。它只能访问静态 Outer 类的成员。

请看这里:https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

【讨论】:

内部“非静态”类也不能声明静态字段或方法 ***类默认是静态的,这就是为什么不能使用 static 关键字的唯一原因。这将是多余的。 (不需要类的实例来访问类,因此它们是静态的)。【参考方案7】:

看到这是“静态类 java”在 Google 上的最高结果,最好的答案不在这里,我想我会添加它。我将 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 系列)(第 18 页)。培生教育。

我认为实施和理由是不言自明的。

【讨论】:

实现单例的好方法。不幸的是,问题不在于单例,而在于静态类 Java 对“static”关键字有相当独特的解释。看起来 OP 来自 C#,其中“静态类”相当于 Java 中的单例。我已经更新了我的答案,以明确对问题的解释。 C# 静态类不是单例。 Singleton 实例是一个对象,可以实现一个接口,这意味着它可以参与依赖注入并且可以被模拟。 C# 静态类不能实现接口或以任何方式注入,更接近于一堆 C 函数,当然允许扩展方法。【参考方案8】:

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

【讨论】:

'Static inner' is a contradiction in terms. 外部类默认是静态的(创建实例不需要实例)【参考方案9】:

简单来说,Java 支持将类声明为仅对内部类是静态的,而对***类不支持。

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

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

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

而且 Java 不支持***类的静态类。

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

【讨论】:

'Static inner' is a contradiction in terms. ***类默认是静态的(不需要实例来访问它们)。由于它们不能是非静态的(您需要它们来创建实例),因此允许使用关键字 static 需要将所有***类表示为静态。这就是不支持该关键字的原因。不代表不支持静态属性。【参考方案10】:

除非是内部类,否则不能对类使用 static 关键字。静态内部类是嵌套类,它是外部类的静态成员。它可以在不实例化外部类的情况下使用其他静态成员进行访问。就像静态成员一样,静态嵌套类无法访问外部类的实例变量和方法。

public class Outer 
   static class Nested_Demo 
      public void my_method() 
          System.out.println("This is my nested class");
      
   
public static void main(String args[]) 
      Outer.Nested_Demo nested = new Outer.Nested_Demo();
      nested.my_method();
   

【讨论】:

你不能在一个类中使用static关键字,除非它是一个嵌套类。 'Static inner' is a contradiction in terms.【参考方案11】:

java中有没有类似静态类的东西?

单例“就像”一个静态类。我很惊讶还没有人提到它们。

public final class ClassSingleton  

private static ClassSingleton INSTANCE;
private String info = "Initial info class";

private ClassSingleton()         


public static ClassSingleton getInstance() 
    if(INSTANCE == null) 
        INSTANCE = new ClassSingleton();
    
    
    return INSTANCE;


// getters and setters

public String getInfo()
    return info;
  

用法类似于:

String infoFromSingleton = ClassSingleton.getInstance().getInfo()

Singleton 非常适合存储 ArrayLists/List/Collection Classes/etc... 如果您经常从多个区域收集、更新、复制集合并需要这些集合同步。或多对一。

【讨论】:

【参考方案12】:

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

【讨论】:

【参考方案13】:

静态方法意味着不需要创建类的对象就可以访问它,不像public:

public class MyClass 
   // Static method
   static void myStaticMethod() 
      System.out.println("Static methods can be called without creating objects");
   

  // Public method
  public void myPublicMethod() 
      System.out.println("Public methods must be called by creating objects");
   

  // Main method
  public static void main(String[ ] args) 
      myStaticMethod(); // Call the static method
    // myPublicMethod(); This would output an error

    MyClass myObj = new MyClass(); // Create an object of MyClass
    myObj.myPublicMethod(); // Call the public method
  

【讨论】:

不回答问题。【参考方案14】:

所有好的答案,但我没有看到对 java.util.Collections 的引用,它使用大量静态内部类作为其静态因子方法。所以添加相同的。

从具有多个静态内部类的 java.util.Collections 添加一个示例。内部类对需要通过外部类访问的代码进行分组非常有用。

/**
 * @serial include
 */
static class UnmodifiableSet<E> extends UnmodifiableCollection<E>
                             implements Set<E>, Serializable 
    private static final long serialVersionUID = -9215047833775013803L;

    UnmodifiableSet(Set<? extends E> s)     super(s);
    public boolean equals(Object o) return o == this || c.equals(o);
    public int hashCode()           return c.hashCode();

这里是 java.util.Collections 类中的静态因子方法

public static <T> Set<T> unmodifiableSet(Set<? extends T> s) 
    return new UnmodifiableSet<>(s);

【讨论】:

'Static inner' is a contradiction in terms. 没有得到您的评论?你能详细说明吗?试图理解您的评论。

以上是关于Java中的静态类的主要内容,如果未能解决你的问题,请参考以下文章

Java中的四种内部类总结

静态类是不是只包含java中的静态方法?

Java中的静态嵌套类,为啥?

Java中的静态方法是啥?

java中的内部类

Java中的静态和枚举