What does the 'static' keyword do in a class?
具体来说,我尝试了以下代码:
1 2 3 4 5 6 7 8 9 10 | package hello; public class Hello { Clock clock = new Clock(); public static void main(String args[]) { clock.sayTime(); } } |
但它给出了错误
Cannot access non-static field in static method main
所以我把EDOCX1的声明改为:
1 | static Clock clock = new Clock(); |
它奏效了。把那个关键字放在声明之前意味着什么?它究竟会做什么和/或限制在什么可以做的对象上?
这意味着一个
由于
旁注:当然,
例子:
1 2 3 4 5 6 7 8 9 10 11 | 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中只有一个"clock"实例,而不是"hello"类的每个单独实例都有一个实例,或者更多,这意味着"hello"类的所有实例中都将有一个共享的"clock"引用。
因此,如果您要在代码中的任何位置执行"新的你好"操作:A-在第一个场景中(在更改之前,不使用"static"),每次调用"new hello"时,它都会生成一个新的时钟,但是B-在第二个场景中(更改之后,使用"static"),每个"new hello"实例仍将共享并使用最初创建的相同"clock"引用。
除非你需要在主系统之外的某个地方"时钟",否则这也会起作用:
1 2 3 4 5 6 7 8 9 | package hello; public class Hello { public static void main(String args[]) { Clock clock=new Clock(); clock.sayTime(); } } |
有关更多信息,请参阅Oracle的Java教程的相关位。
旁白
不幸的是,Java允许您访问静态成员,就像它们是实例成员一样。
1 2 3 |
这使得它看起来好像
1 2 |
Java中的EDCOX1×0 }关键字意味着变量或函数在该类的所有实例之间共享,因为它属于类型,而不是实际对象本身。
因此,如果您有一个变量:
静态方法可以在不实例化对象的情况下使用。
静态成员的基本用法…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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的情况下,如何在所有类成员中共享值的方法。而whit-static则不需要创建类实例。
1 2 | Hello hello = new Hello(); hello.staticValue ="abc"; |
只需按类名调用静态值或方法:
1 | Hello.staticValue ="abc"; |
静态意味着您不必创建类的实例来使用与类关联的方法或变量。在您的示例中,您可以调用:
1 |
直接,而不是:
1 2 | Hello h = new Hello(); h.main(new String[]()); //main(...) is a non-static function linked with the"h" variable |
从静态方法(属于类)内部,您不能访问任何非静态成员,因为它们的值取决于类的实例化。作为实例成员的非静态时钟对象对于Hello类的每个实例都具有不同的值/引用,因此您无法从类的静态部分访问它。
Java中的静态:
静态是非访问修饰符。静态关键字属于类而不是类的实例。可用于将变量或方法附加到类。
静态关键字可用于:
方法
变量
嵌套在另一个类中的类
初始化块
不能用于:
类(不嵌套)
构造函数
界面
方法局部内部类(先差后嵌套类)
内部类方法
实例变量
局部变量
例子:
假设下面的示例有一个名为count的实例变量,该变量在构造函数中递增:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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
由于实例变量在创建对象时获取内存,因此每个对象都将拥有实例变量的副本,如果实例变量递增,则不会反映到其他对象。
现在,如果我们将实例变量计数更改为静态的,那么程序将产生不同的输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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。因此,声明为final和static的变量有时被称为常量。接口的所有字段都被称为常量,因为它们在默认情况下是最终的和静态的。
图片资源:最终静态
到目前为止,这个讨论忽略了类加载器的考虑。严格来说,Java静态字段在给定的类加载器的类的所有实例之间共享。
要添加到现有答案,让我尝试图片:
2%的利率适用于所有储蓄账户。因此它是静态的。
平衡应该是独立的,所以它不是静态的。
可以将字段分配给类或类的实例。默认情况下,字段是实例变量。通过使用
在Java中,EDCOX1的0个关键字可以简单地被视为指示如下:
"without regard or relationship to any particular instance"
如果您以这种方式考虑
static 字段是属于类而不是任何特定实例的字段。static 方法是一种没有this 概念的方法;它是在类上定义的,除非传递一个引用,否则它不知道该类的任何特定实例。static 成员类是一个嵌套类,对其封闭类的实例没有任何概念或知识(除非传递了对封闭类实例的引用)。
静态使时钟成员成为类成员而不是实例成员。如果没有static关键字,则需要创建hello类的实例(该类有一个时钟成员变量),例如
1 2 | Hello hello = new Hello(); hello.clock.sayTime(); |
关键字
问题是,您向类
对于您来说,这意味着对代码进行以下更改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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(); } } |
静态方法不使用在其中定义的类的任何实例变量。在这一页上可以找到一个很好的差异解释。
我已经对"helper"类中的静态方法(只有在可能的情况下)产生了兴趣。
调用类不需要创建助手类的另一个成员(实例)变量。您只需调用helper类的方法。另外,帮助器类也得到了改进,因为您不再需要构造函数,也不需要成员(实例)变量。
可能还有其他优势。
理解静态概念
1 2 3 4 5 6 7 8 9 10 11 | 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 */ } } |
第二课堂
1 2 3 4 5 6 7 8 9 |
还可以考虑没有"this"指针的静态成员。它们在所有实例之间共享。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | //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 } } |
Output: Compile Time Error
静态变量只能在静态方法中访问,所以当我们声明静态变量时,getter和setter方法将是静态方法。
静态方法是我们可以使用类名访问的类级别
下面是静态变量getter和setter的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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; } } |
When run some project firstly load static things(variables, methods, blocks..).
运行此项目时,首先加载主方法。因为它的