In laymans terms, what does 'static' mean in Java?
我已经告诉过它的几个定义,看维基百科,但作为一个初学者Java,我仍然不确定这意味着什么。有人会说Java和白痴吗?
静态意味着标记为静态的变量或方法在类级别上可用。换句话说,您不需要创建类的实例来访问它。
1 2 3 4 5 | public class Foo { public static void doStuff(){ // does stuff } } |
所以,不要创建foo的实例,然后这样调用
1 2 | Foo f = new Foo(); f.doStuff(); |
您只需直接针对类调用方法,如下所示:
1 | Foo.doStuff(); |
在非常外行的术语中,类是一个模子,对象是用该模子制作的副本。静态属于模具,可以直接访问,而不进行任何复制,因此上面的示例
静态关键字可以在Java中以几种不同的方式使用,并且在几乎所有情况下,它都是一个修改器,这意味着它修改的东西在没有封闭对象实例的情况下是可用的。
Java是面向对象的语言,默认情况下,编写的大多数代码都需要使用对象的实例。
1 2 3 4 5 | public class SomeObject { public int someField; public void someMethod() { }; public Class SomeInnerClass { }; } |
为了使用somefield、somemethod或someinnerclass,我必须首先创建someobject的实例。
1 2 3 4 5 6 7 8 9 10 | public class SomeOtherObject { public void doSomeStuff() { SomeObject anInstance = new SomeObject(); anInstance.someField = 7; anInstance.someMethod(); //Non-static inner classes are usually not created outside of the //class instance so you don't normally see this syntax SomeInnerClass blah = anInstance.new SomeInnerClass(); } } |
如果我声明这些东西是静态的,那么它们不需要一个封闭的实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class SomeObjectWithStaticStuff { public static int someField; public static void someMethod() { }; public static Class SomeInnerClass { }; } public class SomeOtherObject { public void doSomeStuff() { SomeObjectWithStaticStuff.someField = 7; SomeObjectWithStaticStuff.someMethod(); SomeObjectWithStaticStuff.SomeInnerClass blah = new SomeObjectWithStaticStuff.SomeInnerClass(); //Or you can also do this if your imports are correct SomeInnerClass blah2 = new SomeInnerClass(); } } |
声明静态的东西有几个含义。
首先,在整个应用程序中,静态字段只能有一个值。
1 2 3 4 5 6 7 8 9 10 11 12 | public class SomeOtherObject { public void doSomeStuff() { //Two objects, two different values SomeObject instanceOne = new SomeObject(); SomeObject instanceTwo = new SomeObject(); instanceOne.someField = 7; instanceTwo.someField = 10; //Static object, only ever one value SomeObjectWithStaticStuff.someField = 7; SomeObjectWithStaticStuff.someField = 10; //Redefines the above set } } |
第二个问题是静态方法和内部类不能访问封闭对象中的字段(因为没有字段)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public class SomeObjectWithStaticStuff { private int nonStaticField; private void nonStaticMethod() { }; public static void someStaticMethod() { nonStaticField = 7; //Not allowed this.nonStaticField = 7; //Not allowed, can never use *this* in static nonStaticMethod(); //Not allowed super.someSuperMethod(); //Not allowed, can never use *super* in static } public static class SomeStaticInnerClass { public void doStuff() { someStaticField = 7; //Not allowed nonStaticMethod(); //Not allowed someStaticMethod(); //This is ok } } } |
静态关键字也可以应用于内部接口、注释和枚举。
1 2 3 4 5 | public class SomeObject { public static interface SomeInterface { }; public static @interface SomeAnnotation { }; public static enum SomeEnum { }; } |
在所有这些情况下,关键字都是多余的,没有效果。接口、注释和枚举在默认情况下是静态的,因为它们从来没有与内部类的关系。
这只是描述他们关键字的作用。它不描述使用关键字是否是一个坏主意。在其他问题中可以更详细地讨论这一点,比如使用大量静态方法是件坏事吗?
关键字static还有一些不太常见的用法。静态导入允许您使用不合格的静态类型(包括接口、注释和未冗余标记为静态的枚举)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | //SomeStaticThing.java public class SomeStaticThing { public static int StaticCounterOne = 0; } //SomeOtherStaticThing.java public class SomeOtherStaticThing { public static int StaticCounterTwo = 0; } //SomeOtherClass.java import static some.package.SomeStaticThing.*; import some.package.SomeOtherStaticThing.*; public class SomeOtherClass { public void doStuff() { StaticCounterOne++; //Ok StaticCounterTwo++; //Not ok SomeOtherStaticThing.StaticCounterTwo++; //Ok } } |
最后,静态初始值设定项是在首次加载类(通常在应用程序中首次实例化类之前)并且(像静态方法一样)无法访问非静态字段或方法时运行的代码块。
1 2 3 4 5 6 7 8 | public class SomeObject { private static int x; static { x = 7; } } |
另一个很好的例子是,当您想要应用单例设计模式时,使用静态属性和操作。简而言之,单例设计模式确保了在系统的生命周期中,一个特定类中只有一个对象是被构造的。为了确保只构建一个对象,单例模式的典型实现保留对单个允许对象实例的内部静态引用,并且使用
除了@inkedmn指出的之外,静态成员还处于类级别。因此,对于该类(当类被加载时),jvm将把上述成员加载到内存中一次。也就是说,没有为所属类的n个实例加载静态成员的n个实例。
以上几点是正确的,我想增加一些关于静态关键字的更重要的要点。
在内部,当您使用静态关键字时,它将存储在永久内存中(即堆内存中),我们知道有两种类型的内存:堆栈内存(临时内存)和堆内存(永久内存),因此如果您不使用静态关键字,则将存储在临时内存中(或者您可以称之为易失性存储器)。
所以你会怀疑这个权利的用途是什么????
示例:静态int a=10;(1个程序)
刚才我告诉过,如果对变量或方法使用静态关键字,它将存储在永久内存中。
所以我在另一个程序中用关键字static声明了相同的变量,值不同。
示例:静态int a=20;(2个程序)
变量"a"由程序1存储在堆内存中。在程序2中找到相同的静态变量"a",此时它不会在堆内存中再次创建"a"变量,而只是替换从10到20的值。
通常,如果不将"a"声明为静态变量,它将在堆栈内存(临时内存)中再次创建变量"a"。
总的来说,如果我们使用静态关键字
 ;1.我们可以保存内存
 ;2.我们可以避免重复
 ;3.无需创建对象即可通过类名访问静态变量,您可以访问它。