简述
- 静态成员变量:在类内数据成员的声明前加上关键字static,该数据成员就是类内的静态数据成员。静态成员变量的值只有一份!
- 静态函数(方法):静态成员函数由于不是与任何的对象相联系,因此它不具有this指 针。从这个意义上讲,它无法访问属于类对象的 非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。
- 静态代码块的特点:静态代码块在装载类的时候执行。
示例.
1.在类体定义一个静态变量,通过两种方式修改,看是不是只修改一个值
class Person{ static int money; public static void talk(String word){ System.out.println(word); } public void saymoney(){ System.out.println(money); } } public class test{ public static void main(String[] agrs){ //1.测试静态成员函数 Person.talk("测试修改静态变量"); Person yanggan=new Person(); Person wangtao=new Person(); Person.talk("--Person.money=500--"); Person.money=500; yanggan.saymoney(); wangtao.saymoney(); Person.talk("--yanggan.money=200--"); yanggan.money=200; yanggan.saymoney(); wangtao.saymoney(); Person.talk("--wangtao.money=123--"); wangtao.money=123; yanggan.saymoney(); wangtao.saymoney(); /* 测试修改静态变量 --Person.money=500--//通过几个不同方式修改,最终修改的都是同一个值 500 500 --yanggan.money=200-- 200 200 --wangtao.money=123-- 123 123 */ } }
2.用静态方法调用动态数据成员,什么结果?
class Person{ String address; public static outputaddress(){ System.out.println(address); /*编译输出: test.java:14: error: invalid method declaration; return type required public static outputaddress(){ ^ 1 error */ /*原因: 如果方法用动态方法,调用动态成员,则address前面隐含了 this. this代表调用的对象。 如果是静态方法,调用动态成员,调用方法为class.outputaddress ,就无法知道address是哪个对象的。 如果静态方法调用静态成员,则唯一的静态变量地址,可以确定 */ } }
2.什么是静态代码块?
class Person{ static{ System.out.println("class Perison 静态代码块执行");// mainy函数为空,为什么放着这里不执行? /* 静态代码块要在装载类的时候,当main函数调用class时候,Person类的静态代码块自动执行 这种代码块的主要作用:用于赋予静态数据成员的初始值 */ } static void say(String word){ System.out.println(word); } } public class test{ static{ System.out.println("class test 静态代码块执行");//放着这个地方可以执行! } public static void main(String[] agrs){ Person.say("装载类"); } }
普通代码块与静态代码块
在Java中,使用”{}”括起来的代码称为代码块,根据代码块的定义位置以及生命的关键字不同,代码块可以分为以下四种:·普通代码块
直接在一个方法中定义为" { } "的无修饰符的代码块;
·构造块
直接在一个类中定义为" { } "的无修饰符的代码块;
·静态块
使用Static声明的代码块,叫做静态块。静态块的重要目的是用来为静态属性初始化。
·同步代码块
同步代码块主要出现在多线程中。
实例
//1.初始化块的测试,初始化块执行在构造器之前而在系统为实例变量分配内存之后 //2.在继承关系中,执行顺序--》父类初始化块-->父类构造器-->子类初始化块-->子类构造器 package me.init; class A{ static{ System.out.println("这是A静态初始化块已经被调用"); } int a=10; A(){ System.out.println("这是A构造器已经被调用"); } { a=900; b=10; System.out.println("这是A初始化块已经被调用"); } int b=100; } class B extends A{ { System.out.println("这是B初始化块被调用"); } B(){ System.out.println("这是B构造器被调用"); } } public class Initcode{ public static void main(String[] args){ //~ A nima=new A(); //~ System.out.println("nima.a= "+nima.a); //~ System.out.println("nima.b= "+nima.b); //~ /*输出: //~ 这是初始化块已经被调用 //~ 这是构造器已经被调用 //~ nima.a= 900//说明代码块与实例变量的赋值并初始化有先后关系 //~ nima.b= 100 //~ *///说明初始化块在构造器之前就运行了 //B nimei =new B(); /*输出: 这是A初始化块已经被调用 这是A构造器已经被调用 这是B初始化块被调用 这是B构造器被调用 */ } }
//学习静态初始化块的执行顺序 package me.init; class Root{ static { System.out.println("ROOT静态初始化块"); } { System.out.println("Root 普通初始化块"); } Root(){ System.out.println("Root 构造器"); } } class Mid extends Root{ static { System.out.println("Mid 静态代码块"); } { System.out.println("Mid 普通代码块"); } Mid(){ System.out.println("Mid 构造器"); } } class Leaf extends Mid{ static { System.out.println("Leaf 静态代码块"); } { System.out.println("Leaf 普通代码块"); } Leaf(){ System.out.println("Leaf 构造器"); } } public class StaticInit{ public static void main(String[] args){ System.out.println("------------------------------"); new Leaf(); System.out.println("------------------------------"); new Leaf(); System.out.println("------------------------------"); } }
作者:YangGan
出处: http://blog.youkuaiyun.com/incyanggan
本文基于 署名 2.5 中国大陆 许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名Yanggan (包含链接).