用俗语来说,”静态”在Java中意味着什么?

In laymans terms, what does 'static' mean in Java?

本问题已经有最佳答案,请猛点这里访问。

我已经告诉过它的几个定义,看维基百科,但作为一个初学者Java,我仍然不确定这意味着什么。有人会说Java和白痴吗?


静态意味着标记为静态的变量或方法在类级别上可用。换句话说,您不需要创建类的实例来访问它。

1
2
3
4
5
public class Foo {
    public static void doStuff(){
        // does stuff
    }
}

所以,不要创建foo的实例,然后这样调用doStuff

1
2
Foo f = new Foo();
f.doStuff();

您只需直接针对类调用方法,如下所示:

1
Foo.doStuff();


在非常外行的术语中,类是一个模子,对象是用该模子制作的副本。静态属于模具,可以直接访问,而不进行任何复制,因此上面的示例


静态关键字可以在Java中以几种不同的方式使用,并且在几乎所有情况下,它都是一个修改器,这意味着它修改的东西在没有封闭对象实例的情况下是可用的。

Java是面向对象的语言,默认情况下,编写的大多数代码都需要使用对象的实例。

1
2
3
4
5
public class SomeObject {
    public int someField;
    public void someMethod() { };
    public Class SomeInnerClass { };
}

为了使用somefield、somemethod或someinnerclass,我必须首先创建someobject的实例。

1
2
3
4
5
6
7
8
9
10
public class SomeOtherObject {
    public void doSomeStuff() {
        SomeObject anInstance = new SomeObject();
        anInstance.someField = 7;
        anInstance.someMethod();
        //Non-static inner classes are usually not created outside of the
        //class instance so you don't normally see this syntax
        SomeInnerClass blah = anInstance.new SomeInnerClass();
    }
}

如果我声明这些东西是静态的,那么它们不需要一个封闭的实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class SomeObjectWithStaticStuff {
    public static int someField;
    public static void someMethod() { };
    public static Class SomeInnerClass { };
}

public class SomeOtherObject {
    public void doSomeStuff() {
        SomeObjectWithStaticStuff.someField = 7;
        SomeObjectWithStaticStuff.someMethod();
        SomeObjectWithStaticStuff.SomeInnerClass blah = new SomeObjectWithStaticStuff.SomeInnerClass();
        //Or you can also do this if your imports are correct
        SomeInnerClass blah2 = new SomeInnerClass();
    }
}

声明静态的东西有几个含义。

首先,在整个应用程序中,静态字段只能有一个值。

1
2
3
4
5
6
7
8
9
10
11
12
public class SomeOtherObject {
    public void doSomeStuff() {
        //Two objects, two different values
        SomeObject instanceOne = new SomeObject();
        SomeObject instanceTwo = new SomeObject();
        instanceOne.someField = 7;
        instanceTwo.someField = 10;
        //Static object, only ever one value
        SomeObjectWithStaticStuff.someField = 7;
        SomeObjectWithStaticStuff.someField = 10; //Redefines the above set
    }
}

第二个问题是静态方法和内部类不能访问封闭对象中的字段(因为没有字段)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class SomeObjectWithStaticStuff {
    private int nonStaticField;
    private void nonStaticMethod() { };

    public static void someStaticMethod() {
        nonStaticField = 7; //Not allowed
        this.nonStaticField = 7; //Not allowed, can never use *this* in static
        nonStaticMethod(); //Not allowed
        super.someSuperMethod(); //Not allowed, can never use *super* in static
    }

    public static class SomeStaticInnerClass {

        public void doStuff() {
            someStaticField = 7; //Not allowed
            nonStaticMethod(); //Not allowed
            someStaticMethod(); //This is ok
        }

    }
}

静态关键字也可以应用于内部接口、注释和枚举。

1
2
3
4
5
public class SomeObject {
    public static interface SomeInterface { };
    public static @interface SomeAnnotation { };
    public static enum SomeEnum { };
}

在所有这些情况下,关键字都是多余的,没有效果。接口、注释和枚举在默认情况下是静态的,因为它们从来没有与内部类的关系。

这只是描述他们关键字的作用。它不描述使用关键字是否是一个坏主意。在其他问题中可以更详细地讨论这一点,比如使用大量静态方法是件坏事吗?

关键字static还有一些不太常见的用法。静态导入允许您使用不合格的静态类型(包括接口、注释和未冗余标记为静态的枚举)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//SomeStaticThing.java
public class SomeStaticThing {
    public static int StaticCounterOne = 0;
}

//SomeOtherStaticThing.java
public class SomeOtherStaticThing {
    public static int StaticCounterTwo = 0;
}

//SomeOtherClass.java
import static some.package.SomeStaticThing.*;
import some.package.SomeOtherStaticThing.*;

public class SomeOtherClass {
    public void doStuff() {
        StaticCounterOne++; //Ok
        StaticCounterTwo++; //Not ok
        SomeOtherStaticThing.StaticCounterTwo++; //Ok
    }
}

最后,静态初始值设定项是在首次加载类(通常在应用程序中首次实例化类之前)并且(像静态方法一样)无法访问非静态字段或方法时运行的代码块。

1
2
3
4
5
6
7
8
public class SomeObject {

    private static int x;

    static {
        x = 7;
    }
}


另一个很好的例子是,当您想要应用单例设计模式时,使用静态属性和操作。简而言之,单例设计模式确保了在系统的生命周期中,一个特定类中只有一个对象是被构造的。为了确保只构建一个对象,单例模式的典型实现保留对单个允许对象实例的内部静态引用,并且使用static操作控制对该实例的访问。


除了@inkedmn指出的之外,静态成员还处于类级别。因此,对于该类(当类被加载时),jvm将把上述成员加载到内存中一次。也就是说,没有为所属类的n个实例加载静态成员的n个实例。


以上几点是正确的,我想增加一些关于静态关键字的更重要的要点。

在内部,当您使用静态关键字时,它将存储在永久内存中(即堆内存中),我们知道有两种类型的内存:堆栈内存(临时内存)和堆内存(永久内存),因此如果您不使用静态关键字,则将存储在临时内存中(或者您可以称之为易失性存储器)。

所以你会怀疑这个权利的用途是什么????

示例:静态int a=10;(1个程序)

刚才我告诉过,如果对变量或方法使用静态关键字,它将存储在永久内存中。

所以我在另一个程序中用关键字static声明了相同的变量,值不同。

示例:静态int a=20;(2个程序)

变量"a"由程序1存储在堆内存中。在程序2中找到相同的静态变量"a",此时它不会在堆内存中再次创建"a"变量,而只是替换从10到20的值。

通常,如果不将"a"声明为静态变量,它将在堆栈内存(临时内存)中再次创建变量"a"。

总的来说,如果我们使用静态关键字
 ;1.我们可以保存内存
 ;2.我们可以避免重复
 ;3.无需创建对象即可通过类名访问静态变量,您可以访问它。