【【static 静态】】
用于修饰成员(成员变量和成员方法/成员函数)
被修饰后的成员具备以下特点:
1、随着类的加载而加载
(随着类的消失而消失,说明它的生命周期最长。比如说相比:static 修饰的属性,和普通属性(对象在,才在。),以及局部变量。)
2、优先与对象存在。 明确一点:静态是先存在(加载时就存在),对象是后存在
3、被所有对象所共享
4、可以直接被类名调用
成员/实例变量和类变量的区别
1,存放位置,
static修饰的类变量随着类的加载而存在与方法区中。
实例变量随着对象的建立而存在堆内存中。
2,生命周期
static修饰的类变量生命周期最长,随着类的消失而消失。
实例变量生命周期随着对象的消失而消失
【使用注意】
静态方法只能访问静态成员(变量或方法)
非静态方法可以访问静态也可以访问非静态
静态方法不可以写this,super 关键字
因为静态优先与对象存在,所以修饰对象的this,和修饰父类的super 都不能存在。
主函数是静态的。
多个对象当中,存在【共同数据】。 这个时候就可以用static进行修饰,不存在就别用静态修饰。
这个时候的静态修饰共享,这个时候将不再堆内存中占用空间。(节约内存空间了。)
静态的有利有弊
利: 对对象共享数据进行单独的空间,节省空间,没有必要每一个对象都存储一份。
可以直接被类名调用
弊:生命周期过长,访问出现局限性。(静态虽然好,却只能访问静态。)
【例子1】static修饰成员变量
/*
* 静态关键字:static,
* 用法:是一个修饰符,用于修饰成员(成员变量,成员方法)
* 当成员静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用,类名.静态成员 {[a1,a2]}
*/
class Person{
String name;
static String country="CN";// [a0]
public void show(){
System.out.println(name+"::"+country);
}
}
public class Guanjz_static{
public static void main(String [] args){
Person p=new Person();
/*
p.name="san";
p.show();
*/
System.out.println(p.country);//[a1]
System.out.println(Person.country);//[a2]
}
}
【例子2】类名调用
public class G_main2 {
public static void main(String []args){
//person_2 p=new person_2();
//p.show();
//我们发现,这样new对象没有什么意义,所以直接用类名调用:
person_2.show();
}
}
class person_2{
String name;
public static void show(){ //static修饰
System.out.println("ttttttttttt");
}
}
【例子4】练习题:
/*执行顺序是。。。
* 注意:由于static优先级,静态代码块只执行一次2大特点
* 所以,先会执行行有main方法中的类,
* 所以先执行了输出语句b,然后执行输出语句c然后进入主函数
* 这个时候new了2次, 但是只执行一次输出语句c,最后输出over语句。
* 结果是 b c a over【a】
* 【mm】
* 注释掉三个[b]
* 添加了一个空参数构造函数、一个代码快、一个带参构造函数、和一个静态方法
* main方法中添加【mm】
* 执行的时候首先执行b和c、a
* 然后因为代码快的执行优先与构造函数,接下来是cc
* 然后执行s=null
* 然后执行带参数的语句,也就是d。
* 所以是b、c、a、cc、d
*/
class StaticCode{
static{ //静态代码块
System.out.println("a");
}
//【a】结束后,注释掉[b]继续下一行:
//【mm】后添加
StaticCode(){
System.out.println("bb");
}
{
System.out.println("cc");
}
StaticCode(int x){
System.out.println("d");
}
public static void show()
{
System.out.println("show run");
}
//【mm】结束
}
public class Demo_static {
static{
System.out.println("b");
}
public static void main(String []args){
//new StaticCode();//[b]
//new StaticCode();//[b]
//System.out.println("over");//[b]
StaticCode s=null;//这个时候【mm】
StaticCode s1=new StaticCode(4);//这个时候【mm】
//目测:出来的是:c a d//【mm】end
}
static{
System.out.println("c");
}
}
当一个对象被实例化时:被静态修饰的成员变量和方法,会首先被放到方法区中,然后才是堆里的属性,然后把地址交给栈里的引用。
黑马官网: http://edu.csdn.net/heima