静 态(static)
定义:有时你希望定义一个类成员,使它的使用完全独立于该类的任何对象。通常情况下,类成员必须通过它的类的对象访问,但是可以创建这样一个成员,它能够被它自己使用,而不必引用特定的实例。在成员的声明前面加上关键字static(静态的)就能创建这样的成员。如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象。你可以将方法和变量都声明为static。static 成员的最常见的例子是main( ) 。因为在程序开始执行时必须调用main() ,所以它被声明为static。
关键字:
Static关键字:可以用于修饰属性,可以用于修饰方法,还可以用于修饰类。
1、 Static修饰属性:无论一个类生成了多少个对象, 所有这些对象共同使用唯一的一份静态的成员变量,一个对该静态成员变量进行了修改,其他对象的改静态成员变量的值也随之发生改变。如果一个成员变量是static的,那么我们可以通过类名.成员变量名的方式来使用它。(推荐用这种方法)。
public class StaticTest2
{
String name = "liming";
int age = 34;
public void info()
{
System.out.println("姓名" + name + "年龄" + age);
}
public static void main(String[] args)
{
StaticTest2 st1 = new StaticTest2();
StaticTest2 st2 = new StaticTest2();
st1.info();
st2.info();
System.out.println("---------");
st1.age=45;//也可由类直接调用StaticTest.age=45;下同
st1.name="zhansan";
st1.info();
st2.info();//st1修改age与name的属性与st2无关,所以st2调用不会改变age与name的属性,打印结果为:liming 34
若将属性改为: static String name = "liming";
static int age = 34;则st1修改age与name的属性与st2有关, st2调用info也会改变age与name的属性,变为:zhansan 45
}
}
如上程序,
2、 Static修饰方法:用static修饰的方法叫静态方法。对于静态方法来说可以使用类名.方法名的方式来访问。
例如:
public class StaticTest {
public static void main(String[] args) {
// TODO Auto-generatedmethod stub
MyStatic ms = new MyStatic();
ms.output();
MyStatic.output();// 使用类名.方法名调用与上面一样!使用static修饰时,通常使用这种方法
}
}
class MyStatic {
public static void output() {
System.out.println("output");
}
}
3、 static在继承中应注意的问题
静态方法只能继承,不能重写(覆盖)。
4、staic代码块:静态代码块
public class FinalTest {
public static void main(String[] args) {
People people = new People();
//属性被final所修饰,不能被改写
}
}
class People {
static{//静态代码块
System.out.println("Static block");
}
}
1)静态代码块的作用是完成一些初始化的工作,首先执行静态代码块,然后执行构造方法。静态代码块在类被加载的时候执行,而构造方法是在生成对象的时候执行,要想调用某个类来生成对象,首先需要将类加载到java虚拟机上(JVM),然后由JVM加载这个类来生成对象。
2)类的静态代码块只会执行一次,是在类被加载的时候执行的,因为每个类只会被加载一次,所以静态代码块也只会被执行一次;而构造方法则不同,每次生成一个对象的时候都会调用类的构造方法,所以new一次就会调用构造方法一次。
3)如果继承体系中既有构造方法,又有静态代码块,那么首先执行最顶层类的静态代码块,一直执行到最底层类的静态代码块,然后再去执行最顶层类的构造方法,一直执行到最底层类的构造方法。注意:静态代码块只会被执行一次。
例如:
public class StaticTest2 {
public static void main(String[] args) {
Q q= new Q();
P p= new P();
}
}
class Q{
static{
System.out.println("Q Staticblock");
}
public Q(){
System.out.println("QConstracter");
}
}
class P extends Q{
static {
System.out.println("P Static block");
}
public P(){
System.out.println("P Constracter");
}
}
将会输出:Q Static block
Q Constracter
P Static block
Q Constracter
P Constracter
5、不能在静态方法中访问非静态的成员变量,可以在静态方法中访问静态的成员变量,也可以在非静态的方法中访问静态的成员变量。
总结:静态的只能访问静态的,非静态的可以访问一切。
6、不能在静态方法中使用this关键字。
注意:
1、 声明为static的变量实质上就是全局变量。当声明一个对象时,并不产生static变量的拷贝,而是该类所有的实例变量共同拥有一个static变量。声明为static的方法有以下几条限制:
1) 它们仅能调用其他的static 方法。
2) 它们只能访问static数据。
3) 它们不能以任何方式引用this 或super(关键字super 与继承有关)。
2、 定义一个静态的属性,它属于整个类的,不属于单个的对象,任何一个对象都可以访问静态的值,访问的都是同一个内存。即使没有对象,也可以访问,用类名加点访问。
3、 类名加上点后面的东西为静态的。例如:
System.out中的out为静态的。
4、在静态方法中不能访问非静态的成员,因为静态方法不属于某一个对象,而非静态的方法属于某一个对象,所以不能访问。想访问非静态的成员,必须new一个出来。