一、static
1、static修饰变量
即静态变量,用于声明独立于对象的静态变量,静态变量是所有对象都共享的,在内存中只有一份拷贝,可以直接使用类名.静态变量名进行访问,当然使用对象访问也是可以的。
下面看个例子加深印象:
public class Person {
private static int sum = 0;
private String name;
public Person(String name) {
this.name = name;
sum++;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Person[] per = new Person[5];
for(int i = 0; i < per.length; i++) {
per[i] = new Person("person" + i);
System.out.println(Person.sum);
}
}
}
假设一个场景,当你正在看直播时,屏幕上会显示有多少个人在看。例子中,每产生一个新的对象都将通过构造函数对sum进行统计累加,结果如下:
用法:值为对象共享时
2、static修饰方法
即静态方法,用于声明独立于对象的静态方法,不需要实例化对象,可以直接通过类名.方法名进行访问,比如初学Java时经常用到的Math类,我们使用它时是直接通过类名.方法名使用的。
public static double pow(double a, double b) {//Math类的静态方法
return StrictMath.pow(a, b); // default impl. delegates to StrictMath
}
public static double random() {//Math类的静态方法
return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
}
注意:在静态方法中,不能调用非静态方法,因为静态方法是伴随着类加载的,而非静态方法对象调用时才出现。同理,非静态变量也是不能够访问的。但是非静态方法可以调用静态方法
class Test{
static int a;
int b;
public Test(int a) {
this.a = a;
}
public static void print() {
//System.out.println(b);//报错
//System.out.println(getA());//报错
System.out.println("类名.print");
}
public int getA() {
return a;
}
}
用法:不需要通过实例化对象的方法
3、static代码块
可存在于类中的任何地方,当类被加载的时候调用一次,换句话说,就是程序运行的时候,只运行一次。可以判断类什么时候被加载。
执行顺序:static块>匿名块(每次创建对象都会被调用执行)>构造函数
主要作用是利用特性可以优化程序性能
下面看个例子:
public class Hero {
private String name ;
private static int life;
private int attack;
private int defense;
static {
//attack = 50;//报错,不允许类变量不是静态的
int i =100;
life = i;
System.out.println(life);
Hero hero = new Hero();
}
{
life = 150;
System.out.println(life);
}
public Hero() {}
public Hero(String name) {
this.name = name;
System.out.println(this.name);
}
public static void main(String[] args) {
Hero h1 = new Hero();
Hero h2 = new Hero("AAA");
}
}
结果:
Hero类被加载时执行一次Static{},输出了100,并实例化一个对象hero,hero则会调用匿名代码块输出150,后面也是如此。
4、static修饰类
使用的较少,暂时没有接触。
二、final
特征:凡是被final修饰的地方都不可改变
1)修饰变量:表示一个常量,不能被修改,只能把值赋值给变量
2)修饰方法:表示方法不能被重写,即被子类继承时,不希望通过子类修改它,但可以重载
3)修饰类:使得该类不能被继承
4)当final修饰引用变量初始化后,不能再指向其他对象,但该引用变量指向的对象内容是可变的,该对象也可以被其他引用变量引用。示例:
class FinalObject
{
int a = 10;
}
public class FinalObjectTest {
public static void main(String[] args) {
final FinalObject obj1 = new FinalObject();
System.out.println(obj1.a);
obj1.a = 20;
System.out.println(obj1.a);
FinalObject obj2 = obj1;
System.out.println(obj2.a);
//obj1 = obj2;//报错
//obj1 = new FinalObject();//报错
//final对象不能变更指针
}
}
补充:
class{
final int a = 5;
static final int b = 10;
}
第一个常量a,只使用final修饰,则每个实例都需要存储该数据,而随着它的使用,内存会不断地分配和释放,而加上static,类加载地时候产生,只需要有一份即可所有对象都共享。
**
第一次写,如有不对或补充的地方,欢迎指正。
**