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

package hello;

public class Hello {

    Clock clock = new Clock();

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

但是它给出了错误

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

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

static Clock clock = new Clock();

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


当前回答

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

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

静态方法可以不实例化对象而使用。

其他回答

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

有关更多信息,请参阅Oracle的Java教程的相关部分。


旁注

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

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

这使它看起来好像sleep是一个实例方法,但实际上它是一个静态方法——它总是使当前线程休眠。更好的做法是在调用代码中清楚地说明这一点:

// Clearer
Thread.sleep(5000);

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

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中的工作方式。

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

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

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

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类的每个实例都有不同的值/引用,因此不能从类的静态部分访问它。