文章目录

  • ​​自增变量​​
  • ​​单例设计模式​​
  • ​​饿汉-直接实例化饿汉式​​
  • ​​饿汉-枚举式​​
  • ​​饿汉-静态代码块​​
  • ​​懒汉式-线程不安全​​
  • ​​懒汉式-线程安全​​
  • ​​懒汉式-静态内部类​​
  • ​​类初始化和实例初始化​​
  • ​​类初始化的过程​​
  • ​​实例初始化的过程​​
  • ​​方法重写​​
  • ​​方法的参数传递机制​​
  • ​​方法的传参机制​​
  • ​​String、包装类等对象的不可变性​​
  • ​​递归与迭代​​
  • ​​递归​​
  • ​​循环递归​​
  • ​​总结​​
  • ​​成员变量与局部变量​​
  • ​​知识点​​
  • ​​解析​​
  • ​​局部变量与成员变量的区别​​
  • ​​jvm内存(扩展)​​
  • ​​重名区分​​

自增变量

1.尚x谷javaSE面试题笔记(1-6)_递归


运行的结果:

1.尚x谷javaSE面试题笔记(1-6)_局部变量_02


解析:

对于:i=i++

1.尚x谷javaSE面试题笔记(1-6)_递归_03


这一行运算完了之后,i的值还是1.上述这个123对应的是字节码的操作。

int j = i++,类似上面,运算完了之后j是1.但是因为i进行了++,所以这一步最终i变成了2.

1.尚x谷javaSE面试题笔记(1-6)_初始化_04


int k = i + ++ii–

1.尚x谷javaSE面试题笔记(1-6)_初始化_05


操作数栈就是你运算的时候还没赋值给某个变量的时候,变量值暂存的地方。局部变量空间就是最终赋值的时候,所在的空间。
也就是说,最后运算的是:int k = 2+3
3=11.

总结:

1.尚x谷javaSE面试题笔记(1-6)_局部变量_06

单例设计模式

1.尚x谷javaSE面试题笔记(1-6)_局部变量_07


1.尚x谷javaSE面试题笔记(1-6)_递归_08

1.尚x谷javaSE面试题笔记(1-6)_局部变量_09

饿汉-直接实例化饿汉式

1.尚x谷javaSE面试题笔记(1-6)_初始化_10

饿汉-枚举式

jdk1.5之后出的这种形式。因为枚举来自1.5版本。

1.尚x谷javaSE面试题笔记(1-6)_递归_11

饿汉-静态代码块

1.尚x谷javaSE面试题笔记(1-6)_初始化_12


效果跟直接饿汉式是一样的。但是负责度上来了。使用场景往往是有变量需要在初始化的时候赋值的时候。如:

1.尚x谷javaSE面试题笔记(1-6)_局部变量_13


饿汉式都是不存在线程安全问题的。在类初始化的时候,直接创建实例对象。

懒汉式-线程不安全

1.尚x谷javaSE面试题笔记(1-6)_局部变量_14


单线程情况下是没有问题的。多线程就出问题了。会创建多个实例。

多线程测试:

1.尚x谷javaSE面试题笔记(1-6)_初始化_15


模拟创建对象的过程:

1.尚x谷javaSE面试题笔记(1-6)_局部变量_16


最终的结果就是创建了 多个实例了。

懒汉式-线程安全

使用同步关键字:

1.尚x谷javaSE面试题笔记(1-6)_递归_17


上面这种方式,实际上是防止创建时候并发,创建完了之后,直接返回就可以了,这样可以改造一下。

1.尚x谷javaSE面试题笔记(1-6)_初始化_18

懒汉式-静态内部类

1.尚x谷javaSE面试题笔记(1-6)_初始化_19


在内部类被加载和初始化时才创建对象。

静态内部类不会随着外部类的加载和初始化而初始化。他是要单独加载和初始化的。这样就实现了延迟创建对象。

因为是在内部类加载和初始化时创建的,因此是线程安全的。

这种方式最简洁,最推荐。

1.尚x谷javaSE面试题笔记(1-6)_初始化_20

类初始化和实例初始化

1.尚x谷javaSE面试题笔记(1-6)_局部变量_21


运行结果:

1.尚x谷javaSE面试题笔记(1-6)_初始化_22

类初始化的过程

1.尚x谷javaSE面试题笔记(1-6)_局部变量_23


所以对于上面,要初始化子类,会先初始化父类。先初始化静态变量和代码块谁在上面谁先初始化。

所以先执行父类的method方法和静态代码块,打印5,1。

然后执行子类的method静态方法和静态代码块,这里静态不存在重写,打印10,6.

实例初始化的过程

1.尚x谷javaSE面试题笔记(1-6)_递归_24


关于super这里声明一点:写或者不写,在子类构造器中一定会调用父类的构造器。

所以:

1.尚x谷javaSE面试题笔记(1-6)_递归_25


所以创建实例会打印:

父类:9-3-2

子类:9-8-7

方法重写

1.尚x谷javaSE面试题笔记(1-6)_初始化_26


1.尚x谷javaSE面试题笔记(1-6)_递归_27


进阶:

1.尚x谷javaSE面试题笔记(1-6)_初始化_28

方法的参数传递机制

1.尚x谷javaSE面试题笔记(1-6)_递归_29


运行结果:num 应该是2

1.尚x谷javaSE面试题笔记(1-6)_局部变量_30


分析:

1.尚x谷javaSE面试题笔记(1-6)_递归_31


然后调用方法,在栈上开辟一块空间存局部变量。发生了实参给形参赋值。内存的变化如下:

1.尚x谷javaSE面试题笔记(1-6)_递归_32


接下来,执行方法里面的操作。要遵循方法的传递机制。

所以i,string,integer,操作完了之后,对原来的变量没有影响。

string拼接之后,在常量池里有了新的地址,发生了重新的指向。integer也是一样的道理。

1.尚x谷javaSE面试题笔记(1-6)_递归_33


对于数组,传递的是地址,所以原来方法里面的数组也发生了变化。对于obj对象,也是传递的地址,对以前对象里面的成员变量发生了改动。

1.尚x谷javaSE面试题笔记(1-6)_初始化_34

方法的传参机制

1.尚x谷javaSE面试题笔记(1-6)_局部变量_35

String、包装类等对象的不可变性

递归与迭代

1.尚x谷javaSE面试题笔记(1-6)_初始化_36


针对这种类型的问题,有2种处理方式,递归或者迭代循环。

递归

进行分析,分析最后一步可能走一步或者两步,抽象出递归的公式。

1.尚x谷javaSE面试题笔记(1-6)_递归_37

代码实现,设计函数f(n):

1.尚x谷javaSE面试题笔记(1-6)_递归_38

循环递归

1.尚x谷javaSE面试题笔记(1-6)_初始化_39


思路就是通过分析,保存前两步的值,加起来就对了,就是我们想要的值。

1.尚x谷javaSE面试题笔记(1-6)_初始化_40

这种写法,不太好理解,编写起来也更复杂。但是解释度比递归要好。

总结

1.尚x谷javaSE面试题笔记(1-6)_初始化_41

成员变量与局部变量

1.尚x谷javaSE面试题笔记(1-6)_递归_42

运行结果:

1.尚x谷javaSE面试题笔记(1-6)_初始化_43

知识点

1.尚x谷javaSE面试题笔记(1-6)_初始化_44

解析

首先非静态代码块中的i是指的非静态代码块中声明的i,这是就近原则。

1.尚x谷javaSE面试题笔记(1-6)_局部变量_45


参数中传进去一个j,然后全局变量也有j,此时就近原则,指的是参数中的j。

1.尚x谷javaSE面试题笔记(1-6)_递归_46


就近原则,还要遵守作用域的限制,所以15行的i指的是全局变量i,不是非静态代码块中的i。

局部变量与成员变量的区别

1.尚x谷javaSE面试题笔记(1-6)_初始化_47


1.尚x谷javaSE面试题笔记(1-6)_局部变量_48


实例变量是有初始化值的,比如你int,初始化值为0.

jvm内存(扩展)

1.尚x谷javaSE面试题笔记(1-6)_局部变量_49


1.尚x谷javaSE面试题笔记(1-6)_初始化_50


对于本题目,jvm三块空间的内存模型:

1.尚x谷javaSE面试题笔记(1-6)_初始化_51

重名区分

1.尚x谷javaSE面试题笔记(1-6)_局部变量_52