【尚硅谷】Java大厂高频面试题(第一季)
考点?
●就近原则
●变量的分类
●成员变量:类变量、实例变量
●局部变量
●非静态代码块的执行:每次创建实例对象都会执行
●方法的调用规则:调用-次执行一次
面试题
结果
分析结果
局部变量与成员变量的区别:
1. 声明的位置
● 局部变量:方法体{}中,形参,代码块{}中
● 成员变量:类中方法外
类变量:有static修饰
实例变量:没有static修饰
2. 修饰符
● 局部变量: final
● 成员变量: public、protected、 private、 final、 static、 volatile、 transient
3. 值存储的位置
● 局部变量:栈
● 实例变量:堆
● 类变量:方法区
4. 作用域
● 局部变量:从声明处开始,到所属的}结束
● 实例变量:在当前类中“this.”(有时this. 可以缺省),在其他类中“对象名.””访问
● 类变量:在当前类中“类名.”(有时类名.可以省略),在其他类中“类名.或“对象名。”访问
5. 生命周期
● 局部变量:每一个线程,每一次调用执行都是新的生命周期
● 实例变量:随着对象的创建而初始化,随着对象的被回收而消亡,每一个对象的实例变量是独立的
● 类变量:随着类的初始化而初始化,随着类的卸载而消亡,该类的所有对象的类变量是共享的
堆(Heap),此内存区域的唯- - 目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。这一点在"Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆.上分配。
通常所说的栈(Stack) ,是指虚拟机栈。虚拟机栈用于存储局部变量表等。局部变量表存放了编译期可知长度的各种基本数据类型( boolean、byte、 char、short、int、 float、long、double) 、对象引用(reference 类型,它不等同于对象本身,是对象在堆内存的首地址)。方法执行完, 自动释放。
**方法区(Method Area)**用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
1. 分析成员变量,局部变量
- 分析成员变量,局部变量
2. 第一句代码执行
- 主方法在本地方法栈开辟空间存放obj1,之前分析过obj1属于局部变量,所以存储在栈中,,在堆中存放obj1的成员变量int i;int j;在栈的obj1指向堆中obj1的成员变量int i;int j;的位置。局部变量没有默认值,但是成员变量都是有默认值的,默认值都为0
- 非静态代码块在实例化其实执行的是
<init>()
,所以就为非静态代码块在栈中开放一块空间,叫做obj1的<init>()
,在里面有一个局部变量int i,初始化为1.然后下面的i++执行,就近原则,这个i是非静态代码块中的这个i,所以i自增,obj1的<init>()
里面局部变量int i变为2.在执行j++,就近原则,j是上面的成员变量,执行j自增,所以,obj1的成员变量int j变为了1。继续向下执行s++,s就近原则,s是上面的类变量,类变量存储在jvm的方法区,在一开是类加载的时候,方法区就存储了数据int s初始化值为0;在非静态代码块中执行s++,方法区的s就变为了1
3. 第二句代码执行
- 第一句代码实例化过程完成之后,存储在栈中的非静态代码块数据就要拿走释放掉了
- 主方法在本地方法栈开辟空间存放obj2,存储在栈中,,在堆中存放obj2的成员变量int i;int j;在栈的obj2指向堆中obj2的成员变量int i;int j;的位置。局部变量没有默认值,但是成员变量都是有默认值的,默认值都为0
- 非静态代码块在实例化其实执行的是
<init>()
,所以就为非静态代码块在栈中开放一块空间,叫做obj2的<init>()
,在里面有一个局部变量int i,初始化为1.然后下面的i++执行,就近原则,这个i是非静态代码块中的这个i,所以i自增,obj2的<init>()
里面局部变量int i变为2.在执行j++,就近原则,j是上面的成员变量,执行j自增,所以,obj2的成员变量int j变为了1。继续向下执行s++,s就近原则,s是上面的类变量,类变量存储在jvm的方法区,在obj1类加载的时候,方法区的s就变为了1,在非静态代码块中执行s++,方法区的s就变为了2.
- 第二句代码实例化过程完成之后,存储在栈中的非静态代码块数据就要拿走释放掉了
4. 第三句代码执行
- 在栈中存储obj1.test()方法,形参局部变量j赋值10,j++改为11。i为成员变量,将obj1的i增加1.
- s为类变量,s++自增1,方法区s变为3
- 释放栈中的数据
5. 第四句代码执行
- 原理同第三句代码
6. 第五句代码执行
当局部变量与xx变量重名时,怎么区分?
- 局部变量与实例变量重名
在实例变量前面加“this.” - 局部变量与类变量重名
在类变量前面加“类名.”