Java 什么是';静态';你在课堂上做什么?

Java 什么是';静态';你在课堂上做什么?,java,static,oop,language-features,restriction,Java,Static,Oop,Language Features,Restriction,具体来说,我尝试了以下代码: package hello; public class Hello { Clock clock = new Clock(); public static void main(String args[]) { clock.sayTime(); } } 但它给出了错误 无法访问静态方法main中的非静态字段 因此,我将时钟的声明更改为: static Clock clock = new Clock(); 它成功了。在声明

具体来说,我尝试了以下代码:

package hello;

public class Hello {

    Clock clock = new Clock();

    public static void main(String args[]) {
        clock.sayTime();
    }
}
但它给出了错误

无法访问静态方法main中的非静态字段

因此,我将
时钟的声明更改为:

static Clock clock = new Clock();

它成功了。在声明之前加上这个关键字意味着什么?就可以对该对象执行的操作而言,它将具体执行和/或限制哪些操作?

静态成员属于类而不是特定实例

Hello hello = new Hello();
hello.staticValue = "abc";
这意味着,即使创建了一百万个类实例或没有创建任何实例,也只存在一个
静态
字段的实例[1]。它将被所有实例共享

由于
static
方法也不属于特定实例,因此它们不能引用实例成员。在给出的示例中,
main
不知道应该引用
Hello
类的哪个实例(因此也不知道应该引用
Clock
类的哪个实例)<代码>静态
成员只能引用
静态
成员。当然,实例成员可以访问
static
成员

旁注:当然,
static
成员可以通过对象引用访问实例成员

例如:

public class Example {
    private static boolean staticField;
    private boolean instanceField;
    public static void main(String[] args) {
        // a static method can access static fields
        staticField = true;

        // a static method can access instance fields through an object reference
        Example instance = new Example();
        instance.instanceField = true;
    }

[1] :根据运行时特征,它可以是每个类加载器、AppDomain或线程一个,但这并不重要。

静态意味着您不必创建类的实例来使用与该类关联的方法或变量。在您的示例中,您可以调用:

Hello.main(new String[]()) //main(...) is declared as a static function in the Hello class
直接,而不是:

Hello h = new Hello();
h.main(new String[]()); //main(...) is a non-static function linked with the "h" variable

从静态方法(属于类)内部,您不能访问任何非静态的成员,因为它们的值取决于您对类的实例化。作为实例成员的非静态时钟对象对Hello类的每个实例都有不同的值/引用,因此您无法从类的静态部分访问它。

这意味着Hello中只有一个“Clock”实例,而不是“Hello”类的每个单独实例都有一个,或者更多,这意味着在“Hello”类的所有实例中都有一个共享的“时钟”引用

因此,如果要在代码中的任何位置执行“新Hello”: A-在第一个场景中(在更改之前,不使用“static”),它会在每次调用“newhello”时生成一个新时钟,但是 B-在第二个场景中(更改后,使用“static”),每个“newhello”实例仍将共享和使用最初创建的初始和相同的“clock”引用

除非您需要在main之外的某个地方使用“时钟”,否则这同样适用:

package hello;
public class Hello
{
    public static void main(String args[])
    {
      Clock clock=new Clock();
      clock.sayTime();    
    }
}

静态使时钟成员成为类成员而不是实例成员。如果没有static关键字,您将需要创建Hello类的实例(它有一个时钟成员变量)


静态方法不使用它们在其中定义的类的任何实例变量。差异的一个很好的解释可以在

上找到,字段可以分配给类或类的实例。默认情况下,字段是实例变量。通过使用
static
字段成为一个类变量,因此只有一个
时钟
。如果你在一个地方做了改变,它随处可见。实例变量彼此独立更改。

到目前为止,本讨论忽略了类加载器的注意事项。严格来说,Java静态字段在给定的类加载器的所有类实例之间共享

也可以认为静态成员没有“this”指针。它们在所有实例之间共享。

Java中的
static
关键字意味着变量或函数在该类的所有实例之间共享,因为它属于该类型,而不是实际对象本身

因此,如果您有一个变量:
private static int i=0i++
),更改将反映在所有实例中<代码>i
现在在所有情况下都将是1


静态方法可以在不实例化对象的情况下使用。

Static
关键字意味着某些内容(字段、方法或嵌套类)与类型相关,而不是与类型的任何特定实例相关。例如,调用
Math.sin(…)
时,没有
Math
类的任何实例,实际上您无法创建
Math
类的实例

有关更多信息,请参阅


旁注

不幸的是,Java允许您像访问实例成员一样访问静态成员,例如

// Bad code!
Thread.currentThread().sleep(5000);
someOtherThread.sleep(5000);
这使它看起来好像
sleep
是一个实例方法,但实际上它是一个静态方法-它总是使当前线程处于睡眠状态。最好在调用代码中明确这一点:

// Clearer
Thread.sleep(5000);

我喜欢“helper”类中的静态方法(只有在可能的情况下)

调用类不需要创建helper类的另一个成员(实例)变量。您只需调用helper类的方法。此外,helper类也得到了改进,因为您不再需要构造函数,也不需要成员(实例)变量


可能还有其他优势。

静态成员的基本用法

public class Hello
{
    // value / method
    public static String staticValue;
    public String nonStaticValue;
}

class A
{
    Hello hello = new Hello();
    hello.staticValue = "abc";
    hello.nonStaticValue = "xyz";
}

class B
{
    Hello hello2 = new Hello(); // here staticValue = "abc"
    hello2.staticValue; // will have value of "abc"
    hello2.nonStaticValue; // will have value of null
}
这就是如何在所有类成员中共享值,而无需向其他类发送类实例Hello。在静态的情况下,您不需要创建类实例

Hello hello = new Hello();
hello.staticValue = "abc";
只需按类名调用静态值或方法即可:

Hello.staticValue = "abc";

关键字
static
用于表示字段或方法属于类本身而不是实例。使用您的代码,如果对象
Clock
是静态的,那么
Hello
类的所有实例都将共享此
Clock
数据成员(字段)。如果将其设置为非静态,则
Hello的每个单独实例<
package hello;

public class Hello {

    private Clock clock = new Clock();

    public Clock getClock() {
        return clock;
    }

    public static void main(String args[]) {
        Hello hello = new Hello();
        hello.getClock().sayTime();
    }
}
class A {  
    int a = 40; //non static
    public static void main(String args[]) {  
        System.out.println(a);  
    }  
}
public class Static 
{

    private static String owner;
    private static int rent;
    private String car;
    public String getCar() {
        return car;
    }
    public void setCar(String car) {
        this.car = car;
    }
    public static int getRent() {
        return rent;
    }
    public static void setRent(int rent) {
        Static.rent = rent;
    }
    public static String getOwner() {
        return owner;
    }

    public static void setOwner(String owner) {
        Static.owner = owner;
    }

}
package pkg;

class StaticExample {
    int count = 0;// will get memory when instance is created

    StaticExample() {
        count++;
        System.out.println(count);
    }

    public static void main(String args[]) {

        StaticExample c1 = new StaticExample();
        StaticExample c2 = new StaticExample();
        StaticExample c3 = new StaticExample();

    }
}
package pkg;

class StaticExample {
    static int count = 0;// will get memory when instance is created

    StaticExample() {
        count++;
        System.out.println(count);
    }

    public static void main(String args[]) {

        StaticExample c1 = new StaticExample();
        StaticExample c2 = new StaticExample();
        StaticExample c3 = new StaticExample();

    }
}
public class StaticPractise1 {
    public static void main(String[] args) {
        StaticPractise2 staticPractise2 = new StaticPractise2();
        staticPractise2.printUddhav(); //true
        StaticPractise2.printUddhav(); /* false, because printUddhav() is although inside StaticPractise2, but it is where exactly depends on PC program counter on runtime. */

        StaticPractise2.printUddhavsStatic1(); //true
        staticPractise2.printUddhavsStatic1(); /*false, because, when staticPractise2 is blueprinted, it tracks everything other than static  things and it organizes in its own heap. So, class static methods, object can't reference */

    }
}
public class StaticPractise2 {
    public static void printUddhavsStatic1() {
        System.out.println("Uddhav");
    }

    public void printUddhav() {
        System.out.println("Uddhav");
    }
}
//Here is an example 

public class StaticClass 
{
    static int version;
    public void printVersion() {
         System.out.println(version);
    }
}

public class MainClass 
{
    public static void main(String args[]) {  
        StaticClass staticVar1 = new StaticClass();
        staticVar1.version = 10;
        staticVar1.printVersion() // Output 10

        StaticClass staticVar2 = new StaticClass();
        staticVar2.printVersion() // Output 10
        staticVar2.version = 20;
        staticVar2.printVersion() // Output 20
        staticVar1.printVersion() // Output 20
    }
}
    void f() {
        int foo = 1;
        static int bar = 2;
         :
    }
    class C {
        int foo = 1;
        static int bar = 2;
         :
    }
    class C {
        int foo() { ... }
        static int bar() { ... }
         :
    }