Java中的静态类

时间:2011-09-20 13:32:42

标签: java static-classes

java中是否有类似static class的内容?

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

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

什么是静态类?

14 个答案:

答案 0 :(得分:793)

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类确实是静态的。

答案 1 :(得分:298)

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

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

Java中没有顶级静态类。

答案 2 :(得分:143)

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

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

代码示例:

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

答案 3 :(得分:93)

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

示例:

public class A
{

 public static class B
 {
 }
}

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

B b = new B();

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

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

答案 4 :(得分:31)

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

但我们不能在static内部类中拥有non-static个成员。

答案 5 :(得分: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() { ... }
}
     

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

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

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

答案 6 :(得分:12)

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

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

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

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

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

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

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

答案 7 :(得分:9)

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

答案 8 :(得分:1)

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

答案 9 :(得分:1)

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

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

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

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

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

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

答案 10 :(得分:1)

使用静态类非常有利于分组。因为Java允许我们对彼此有用的类进行分组,所以我们将它们分组只是为了使它们在单个关键字static下保持在一起。

Java支持嵌套类,它们可以是静态的。这些静态类也称为静态嵌套类。 Java静态嵌套类只能访问外部类的静态成员。静态嵌套类的行为与顶级类相似,并且嵌套只是为了包装上的方便。

让我们看一下Java静态类的示例,并了解如何在Java程序中使用它。

public class OuterClass {

private static String name = "Mohammad";

// static nested class
static class StaticNestedClass {
    private int a;

    public int getA() {
        return this.a;
    }

    public String getName() {
        return name;
    }
  }
}

现在让我们看看如何实例化和使用静态嵌套类。

public class StaticNestedClassTest {

public static void main(String[] args) {

    //creating instance of static nested class
    OuterClass.StaticNestedClass nested = new OuterClass.StaticNestedClass();

    //accessing outer class static member
    System.out.println(nested.getName());    // Printing "Mohammad"
    }
}

在此处查看更多详细信息:

Understanding Static Class in Java | Java Nested Class

Static class in Java

Java Static Class: A step further in your Java programming journey

Java Nested and Inner Class

答案 11 :(得分:1)

静态方法意味着可以访问它而无需创建类的对象,这与public不同:

var myDict = new Dictionary<EnumTypeEtatIdee, string>(){
    {EnumTypeEtatIdee.example, "example"},
    {EnumTypeEtatIdee.exampletwo, "Aletude"},
    {EnumTypeEtatIdee.examplethree, "Encours"},
    {EnumTypeEtatIdee.examplefour, "examplefour"},
    {EnumTypeEtatIdee.examplefive, "examplefive"},
};

var CssClass = "null";
if (myDict.ContainsKey((EnumTypeEtatIdee)idee.IdTypeEtatIdee)){
    CssClass = myDict[(EnumTypeEtatIdee)idee.IdTypeEtatIdee];
}

答案 12 :(得分:0)

除非类是内部类,否则不能将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();
   }
}

答案 13 :(得分:-1)

所有好的答案,但是我没有看到对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);
}