用外行人的话来说,Java中“静态”意味着什么? [重复]

问题描述 投票:93回答:6

这个问题在这里已有答案:

我被告知了几个定义,在维基百科上看,但作为Java的初学者,我仍然不确定它的含义。有流利的Java和白痴吗?

java static reference
6个回答
234
投票

static表示标记为此类的变量或方法在类级别可用。换句话说,您不需要创建类的实例来访问它。

public class Foo {
    public static void doStuff(){
        // does stuff
    }
}

所以,不要创建一个Foo实例,然后像这样调用doStuff

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

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

Foo.doStuff();

37
投票

在非常外行的情况下,该类是模具,对象是用该模具制作的副本。静态属于模具,可以直接访问而无需进行任何复制,因此上面的示例


14
投票

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

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

public class SomeObject {
    public int someField;
    public void someMethod() { };
    public Class SomeInnerClass { };
}

为了使用someField,someMethod或SomeInnerClass,我必须首先创建SomeObject的一个实例。

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

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

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

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

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

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
    }
}

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

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
        }

    }
}

static关键字也可以应用于内部接口,注释和枚举。

public class SomeObject {
    public static interface SomeInterface { };
    public static @interface SomeAnnotation { };
    public static enum SomeEnum { };
}

在所有这些情况下,关键字都是多余的,没有任何效果。默认情况下,接口,注释和枚举是静态的,因为它们永远不会与内部类建立关系。

这只是描述了他们关键字的作用。它没有描述关键字的使用是否是一个坏主意。这可以在其他问题中更详细地介绍,例如Is using a lot of static methods a bad thing?

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

//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
    }
}

最后,有一些静态初始化器,它们是在第一次加载类时运行的代码块(通常就是在应用程序中第一次实例化类之前)和(如静态方法)无法访问非静态字段或方法。

public class SomeObject {

    private static int x;

    static {
        x = 7;
    }
}

7
投票

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


3
投票

除了@inkedmn所指出的,静态成员是在类级别。因此,所述成员由JVM一次为该类加载到内存中(当加载类时)。也就是说,没有为其所属的类的n个实例加载静态成员的n个实例。


-4
投票

以上几点是正确的,我想补充一些关于Static关键字的重点。

在内部使用static关键字时会发生什么,它会存储在永久内存中(即在堆内存中),我们知道它们有两种类型的内存,它们是堆栈内存(临时内存)和堆内存(永久内存),所以如果您不使用静态关键字,则将存储在堆栈内存中的临时内存中(或者您可以将其称为易失性内存)。

所以你会怀疑这个有什么用?

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

刚才我告诉你是否对变量或方法使用静态关键字,它将存储在永久存储器中。

所以我在其他程序中用不同的值声明了与关键字static相同的变量。

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

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

一般来说,如果你不将'a'声明为静态变量,它将在堆栈内存(临时内存)中再次创建变量'a'。

总的来说我可以说,如果我们使用静态关键字 我们可以节省记忆 我们可以避免重复 3.无需在类名的帮助下按顺序创建对象以访问静态变量,您可以访问它。

© www.soinside.com 2019 - 2024. All rights reserved.