类和对象、静态变量、实例变量、final和static修饰符的总结
-
类和对象
类:具有相同特征的集合抽象成的的模板
对象:具有某种特征的事物
(个人认为最好的例子就是学生群体和该群体某个学生李四) -
静态变量和实例变量
静态变量又叫类变量,依托于类,和有没有对象无关
实例变量就是成员变量,必须依赖于对象
静态方法和成员方法类似关系 -
final和static修饰符
final:修饰的变量一旦被初始化,是不能再修改的,所以看成常量
static:可以修饰变量、方法和代码块,表明其是静态的,
this: 由static引出this的使用方法,this是一种隐式参数,在类中this相当于正在运行的对象或者实例。 -
类、对象、静态、实例在程序运行中的顺序,参见以下代码
public class Employee {
public static int nextId ;
public static final String card="初始化";
private int ID;
static {
System.out.println("静态代码块");
System.out.println("初始化的card:"+card);
System.out.println("----------------------");
}
{
System.out.println("实例代码块1");
System.out.println("---------------");
}
public Employee(int aID) {
ID = aID;
System.out.println("执行有参构造");
System.out.println("ID:"+this.ID);
System.out.println("----------------------\n\n");
}
{
System.out.println("实例代码块2");
System.out.println("ID:"+this.ID);
System.out.println("---------------------");
}
public void setNextId() {
nextId++;
System.out.println("静态字段nextID为:" + nextId);
System.out.println("---------------------");
}
//普通方法
public void Employee() {
final int a=10;
System.out.println("普通方法");
System.out.println("a为"+a);
}
}
在另一个包中建个测试类
public class EmployeeTest {
public static void main(String[] args) {
System.out.println("程序入口");
Employee employee1=new Employee(1);
Employee employee2=new Employee(2);
employee1.setNextId();
employee2.setNextId();
employee1.setNextId();
employee1.Employee();
}
}
程序输出如下:
程序入口
静态代码块
初始化的card:初始化
----------------------
实例代码块1
---------------
实例代码块2
ID:0
---------------------
执行有参构造
ID:1
----------------------
实例代码块1
---------------
实例代码块2
ID:0
---------------------
执行有参构造
ID:2
----------------------
静态字段nextID为:1
----------------------
静态字段nextID为:2
----------------------
静态字段nextID为:3
----------------------
普通方法
a为10
由以上输出结果我们可以得到:
-
程序最先是在main()j进入的,所以输出"程序入口". 在测试类中往下走代码,当遇到类时,jvm会加载类,==而静态的字段(变量)就在此时被初始化,并执行输出静态代码块中”静态代码块“==静态的东西在类加载的时候就执行了一次,且只会执行这一次,其生命周期和类一样长,故”静态代码块“只输出了一次
-
加载完类之后,程序执行new右边的Employee(1);,新建了一个对象,注意,新建对象时并没有操作构造函数里的赋值,而是先初始化实例变量,输出实例代码块,再执行实例变量的赋值操作,故程序先输出”实例代码块1“和”实例代码块2 ID:0“,(此处ID仍然为初始化的值0)main中new完对象后,将对象地址值赋值给emploee1,
-
执行employee1.setNextId(); employee2.setNextId();employee1.setNextId();后,注意到nextID每次都加1了,说明用不同的对象操作静态变量后,其他对象中的静态变量也发生了变化,说明静态变量不依赖与对象。
-
关于类和对象在内存中存储的问题:
类加载时,类的字段存储于元空间,程序新建对象时,依据类的模板,将新建的对象成员变量存储于堆上,而成员方法仍在元空间,方法内定义的基本变量和变量数值存储于栈,若有引用类型,则引用变量只是指向该引用对象的地址值,引用对象在堆上。 -
final修饰的变量初始化后不能改变,其存储于常量池
-
注意this指的是对象,由于类刚加载时没有对象,故类加载时执行的静态代码块或者静态方法、字段,不能使用this。