具体来说,我正在尝试这段代码:

package hello;

public class Hello {

    Clock clock = new Clock();

    public static void main(String args[]) {
        clock.sayTime();
    }
}

但它给出了错误

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

所以我改变了声明 clock 对此:

static Clock clock = new Clock();

它起作用了。将关键字放在声明之前是什么意思?它到底会做什么和/或限制对该对象可以做什么?

有帮助吗?

解决方案

static 成员属于该类而不是特定实例。

这意味着只有 static 字段的一个实例 [1] ,即使你创建了一百万个类的实例,或者你不要创造任何。它将由所有实例共享。

由于 static 方法也不属于特定实例,因此它们不能引用实例成员。在给出的示例中, main 不知道它应引用的 Hello 类的哪个实例(以及 Clock 类的哪个实例) 。 static 成员只能引用 static 成员。实例成员当然可以访问 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]:根据运行时特性,它可以是每个ClassLoader或AppDomain或线程一个,但这不是重点。

其他提示

这意味着只有一个“时钟”实例。在Hello中,不是每个单独的“Hello”实例中的一个。类,或更多 - 这意味着将有一个共同的“时钟”。 “Hello”的所有实例中的引用类。

所以,如果你要做一个“新的Hello”。代码中的任何位置: 在第一种情况下(在改变之前,不使用“静态”),它将在每次“新的Hello”时产生新的时钟。叫,但是 B-在第二种情况下(在改变之后,使用“静态”),每个“新的”Hello“实例仍将共享和使用初始和相同的“时钟”。引用首次创建。

除非你需要“时钟”在main之外的某个地方,这也可以起作用:

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

static 关键字表示某些内容(字段,方法或嵌套类)与类型相关,而不是任何特定的实例类型。例如,一个调用 Math.sin(...)而没有任何 Math 类的实例,实际上你不能创建 Math 类的一个实例。

有关详细信息,请参阅 Oracle Java教程的相关内容


<强>旁注

遗憾的是, 允许您访问静态成员,就好像它们是实例成员一样,例如

// Bad code!
Thread.currentThread().sleep(5000);
someOtherThread.sleep(5000);

这使看起来好像 sleep 是一个实例方法,但它实际上是一个静态方法 - 总是使当前线程睡眠。最好在调用代码中明确这一点:

// Clearer
Thread.sleep(5000);

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

因此,如果您有一个变量: private static int i = 0; 并在一个实例中递增它( i ++ ),则更改将反映在所有实例中。 i 现在在所有情况下都是1。

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

静态成员的基本用法......

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";

Java中的静态:

Static是非访问修饰符。 static关键字属于类而不是类的实例。 可用于将变量或方法附加到类。

静态关键字可用于:

方法

可变

嵌套在另一个类

中的类

初始化块

不能用于:

类(非嵌套)

构造

接口

方法本地内部类(差异然后是嵌套类)

内部类方法

实例变量

本地变量

示例:

想象一下以下示例,其中有一个名为count 实例变量,它在构造函数中递增:

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

    }
}

<强>输出:

  

1 1 1

由于实例变量在创建对象时获取内存,因此每个对象都将具有实例变量的副本,如果增加,则不会反映到其他对象。

现在,如果我们将实例变量计数更改为静态,那么程序将生成不同的输出:

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

    }
}

<强>输出:

  

1 2 3

在这种情况下,静态变量只会获取一次内存,如果任何对象改变了静态变量的值,它将保留其值。

静态与决赛:

声明为 final和static 的全局变量在整个执行过程中保持不变。因为,静态成员存储在类内存中,并且在整个执行过程中只加载一次。它们对于该类的所有对象都是通用的。如果将静态变量声明为final,则任何对象都不能更改它们的最终值。因此,声明为final和static的变量有时称为常量。接口的所有字段都称为常量,因为默认情况下它们是final和static。

图片资源:最终静态

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

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

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

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

要添加到现有答案,让我试试图片:

2%的利率适用于所有储蓄账户。因此它是静态

余额应个人,因此是静态的。

可以将字段分配给类或类的实例。默认情况下,字段是实例变量。通过使用 static ,字段变为类变量,因此只有一个 clock 。如果您在一个地方进行更改,它随处可见。实例可变数据彼此独立地更改。

关键字 static 用于将字段或方法表示为属于类本身而不是实例。使用您的代码,如果对象 Clock 是静态的, Hello 类的所有实例将共享此 Clock 数据成员(字段)in共同。如果你使它成为非静态的, Hello 的每个实例都可以有一个唯一的 Clock 字段。

问题是您在类 Hello 中添加了 main 方法,以便您可以运行代码。这里的问题是 main 方法是静态的,因此,它不能引用其中的非静态字段或方法。您可以通过两种方式解决此问题:

  1. 使 Hello 类的所有字段和方法都是静态的,以便可以在 main 方法中引用它们。这真的不是一件好事(或者使字段和/或方法静态的错误原因)
  2. 在main方法中创建 Hello 类的实例,并按照它们最初的方式访问它们的所有字段和方法。
  3. 对您而言,这意味着对您的代码进行了以下更改:

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

在Java中, static 关键字可以简单地视为表示以下内容:

“不考虑或与任何特定实例无关”

如果你想到 static 通过这种方式,可以更容易地理解它在遇到它的各种上下文中的用法:

  • A static field 是属于类而不是任何特定实例的字段

  • A static 方法是一种没有概念的方法 this;它是在类上定义的,并且不知道该类的任何特定实例,除非将引用传递给它

  • A static 成员类是一个嵌套类,对其封闭类的实例没有任何概念或了解(除非将对其封闭类实例的引用传递给它)

Static使clock成员成为类成员而不是实例成员。如果没有static关键字,则需要创建Hello类的实例(具有时钟成员变量) - 例如。

Hello hello = new Hello();
hello.clock.sayTime();

静态方法不使用它们所定义的类的任何实例变量。可以在此页

我已经开始喜欢“助手”中的静态方法(如果可能的话)。类。

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

可能还有其他优点。

还可以想到没有“这个”的静态成员。指针。它们在所有实例之间共享。

了解静态概念

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

main()是一个静态方法,它有两个基本限制:

  1. 静态方法不能使用非静态数据成员或直接调用非静态方法。
  2. this() super()不能在静态上下文中使用。

    class A {  
        int a = 40; //non static
        public static void main(String args[]) {  
            System.out.println(a);  
        }  
    }
    
  3.   

    输出:编译时间错误

静态变量只能在静态方法中访问,所以当我们声明静态变量时,那些getter和setter方法将是静态方法

静态方法是我们可以使用类名

访问的类级别

以下是静态变量Getters和Setter的示例:

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

}
  

当运行某个项目时,首先加载静态事物(变量,方法,块......)。

运行此项目时,首先加载主方法。因为它的静态方法。然后它看起来是对象&quot; a&quot;对象。但是对象尚未定义。因为它非静电。然后就像这个错误。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top