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

package hello;

public class Hello {

    Clock clock = new Clock();

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

但是它给出了错误

不能访问静态方法主中的非静态字段

所以我把时钟的声明改为这样:

static Clock clock = new Clock();

这招奏效了。将该关键字放在声明之前意味着什么?它究竟会做什么和/或限制可以对该对象做什么?


当前回答

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

其他回答

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

您向Hello类添加了一个主方法,以便可以运行代码。这样做的问题是,主方法是静态的,因此,它不能引用其中的非静态字段或方法。你可以用两种方法来解决这个问题:

将Hello类的所有字段和方法设置为静态的,以便在主方法中引用它们。这不是一件好事(或者是将字段和/或方法设置为静态的错误原因) 在主方法中创建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();
    }
}

静态成员的基本用法…

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

我喜欢在“助手”类中使用静态方法(如果可能的话)。

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

或许还有其他优势。

Java程序中的成员可以在其声明/定义之前使用关键字“static”声明为static。当成员声明为静态时,本质上意味着该成员由类的所有实例共享,而无需为每个实例复制。

因此static是Java中使用的非类修饰符,可以应用于以下成员:

变量 方法 块 类(更确切地说,嵌套类)

当成员被声明为静态时,可以不使用对象访问它。这意味着在实例化类之前,静态成员是活动的并且是可访问的。与其他非静态类成员不同的是,当类的对象超出作用域时,类成员就不再存在,而静态成员显然仍然是活动的。

Java中的静态变量

类中声明为静态的成员变量称为静态变量。它也被称为“类变量”。一旦变量声明为静态,内存只分配一次,而不是在类实例化时每次都分配。因此,您可以在不引用对象的情况下访问静态变量。

下面的Java程序描述了静态变量的用法:

class Main
{
// static variables a and b
static int a = 10;
static int b;

static void printStatic()
{
    a = a /2;
    b = a;

    System.out.println("printStatic::Value of a : "+a + " Value of b : 
 "+b);
}  

public static void main(String[] args)
{
   printStatic();
   b = a*5;
   a++;

System.out.println("main::Value of a : "+a + " Value of b : "+b);
   }
 }

输出:

printStatic::Value of a : Value of b : 5
main::Value of a : 6 Value of b : 25

在上面的程序中,我们有两个静态变量,即a和b。我们在函数“printStatic”和“main”中修改这些变量。请注意,即使函数的作用域结束,这些静态变量的值也会在函数之间保留。输出显示了两个函数中变量的值。

静态方法

在Java中,当一个方法前面带有关键字“static”时,该方法就是静态的。

关于静态方法,你需要记住的要点包括:

A static method belongs to the class as against other non-static methods that are invoked using the instance of a class. To invoke a static method, you don’t need a class object. The static data members of the class are accessible to the static method. The static method can even change the values of the static data member. A static method cannot have a reference to ‘this’ or ‘super’ members. Even if a static method tries to refer them, it will be a compiler error. Just like static data, the static method can also call other static methods. A static method cannot refer to non-static data members or variables and cannot call non-static methods too.

下面的程序显示了静态方法在Java中的实现:

class Main
{
  // static method
  static void static_method()
{
    System.out.println("Static method in Java...called without any 
object");
}

public static void main(String[] args)
{
    static_method();
   }
 }

输出:

Static method in Java...called without any object

Java中的静态块

就像在c++、c#等编程语言中有函数块一样,在Java中也有一个特殊的块,称为“静态”块,通常包括与静态数据相关的代码块。

这个静态块在创建类的第一个对象时(准确地说是在类加载时)或在块内的静态成员被使用时执行。

下面的程序展示了静态块的用法。

class Main
{
  static int sum = 0;
  static int val1 = 5;
  static int val2;

// static block
 static {
    sum = val1 + val2;
    System.out.println("In static block, val1: " + val1  + " val2: "+ 
val2 + " sum:" + sum);
    val2 = val1 * 3;
    sum = val1 + val2;
}

 public static void main(String[] args)
{
    System.out.println("In main function, val1: " + val1  + " val2: "+ val2 + " sum:" + sum);
  }
}

输出:

In static block, val1: 5 val2: 0 sum:5
In main function, val1: val2: 15 sum:20

静态类

在Java中,有静态块、静态方法,甚至静态变量。因此,很明显,您也可以拥有静态类。在Java中,可以将一个类放在另一个类中,这被称为嵌套类。包含嵌套类的类称为外层类。

在Java中,虽然可以将嵌套类声明为Static,但不能将外部类声明为Static。

现在让我们研究Java中的静态嵌套类。

静态嵌套类

如前所述,可以将Java中的嵌套类声明为静态类。静态嵌套类与非静态嵌套类(内部类)在某些方面有所不同,如下所示。

与非静态嵌套类不同,嵌套静态类不需要外部类引用。

静态嵌套类只能访问外部类的静态成员,而非静态类可以访问外部类的静态成员和非静态成员。

下面给出了一个静态嵌套类的示例。


class Main{
  private static String str = "SoftwareTestingHelp";

     //Static nested class
     static class NestedClass{
        //non-static method
            public void display() {

            System.out.println("Static string in OuterClass: " + str);
            }

    }
   public static void main(String args[])
   {
            Main.NestedClassobj = new Main.NestedClass();
            obj.display();
   }
}

输出

Static string in OuterClass: SoftwareTestingHelp

我认为这就是静态关键字在java中的工作方式。

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