解析Java常考面试题----本文会持续更新

本文会持续更新,敬请期待......

----------------------------------------------更新于2019/3/26 9:58-----------------------------------------------

3、Java虚拟机类加载机制


  
  1. public class StaticTest
  2. {
  3. public static void main(String[] args) {
  4. staticFunction();
  5. }
  6. static StaticTest st = new StaticTest();
  7. static {
  8. System.out.println("1");
  9. }
  10. {
  11. System.out.println("2");
  12. }
  13. StaticTest() {
  14. System.out.println("3");
  15. System.out.println("a="+a+",b="+b);
  16. }
  17. public static void staticFunction(){
  18. System.out.println("4");
  19. }
  20. int a=110;
  21. static int b =112;
  22. }
  23. /**
  24. 正确答案:
  25. 2
  26. 3
  27. a=110,b=0
  28. 1
  29. 4
  30. */

这里主要的点之一:实例初始化不一定要在类初始化结束之后才开始初始化 

类的生命周期是:加载->验证->准备->解析->初始化->使用->卸载。

只有在准备阶段初始化阶段才会涉及类变量的初始化和赋值,因此只针对这两个阶段进行分析;

类的准备阶段需要做是为类变量分配内存并设置默认值,因此类变量st为null、b为0;

类的初始化阶段需要做的是执行类构造器。

类构造器是编译器收集所有静态语句块和类变量的赋值语句,按语句在源码中的顺序合并生成类构造器,对象的构造方法是(),类的构造方法是(),可以在堆栈信息中看到。

Java中赋值顺序:

  1. 父类的静态变量赋值
  2. 自身的静态变量赋值
  3. 父类成员变量赋值和父类块赋值
  4. 父类构造函数赋值
  5. 自身成员变量赋值和自身块赋值
  6. 自身构造函数赋值

如下问题:


  
  1. public class Test {
  2. public static void main(String[] args) {
  3. func();
  4. }
  5. static Test st = new Test();
  6. static void func(){}
  7. }

根据上面的代码,有以下步骤:

  1. 首先在执行此段代码时,首先由main方法的调用触发静态初始化。
  2. 在初始化Test 类的静态部分时,遇到st这个成员。
  3. 但凑巧这个变量引用的是本类的实例。
  4. 那么问题来了,此时静态初始化过程还没完成就要初始化实例部分了。是这样么?
  5. 从人的角度是的。但从java的角度,一旦开始初始化静态部分,无论是否完成,后续都不会再重新触发静态初始化流程了。
  6. 因此在实例化st变量时,实际上是把实例初始化嵌入到了静态初始化流程中,并且在楼主的问题中,嵌入到了静态初始化的起始位置。这就导致了实例初始化完全至于静态初始化之前。这也是导致a有值b没值的原因。
  7. 最后再考虑到文本顺序,结果就显而易见了。

----------------------------------------------更新于2019/2/28 12:31-----------------------------------------------

2、讲述SpringMVC工作流程

工作流程 
1、用户发送请求至前端控制器DispatcherServlet 
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。 
3、处理器映射器找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。 
4、DispatcherServlet调用HandlerAdapter处理器适配器 
5、HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。 
6、Controller执行完成返回ModelAndView 
7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet 
8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器 
9、ViewReslover解析后返回具体View 
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。 
11、DispatcherServlet响应用户

 

----------------------------------------------开始于2019/2/26 13:16-----------------------------------------------

1、自增变量代码分析:


  
  1. public static void main(String[] args) {
  2. int i = 1; //第一行
  3. i = i++; //第二行
  4. int j = i++;//第三行
  5. int k = i+ ++i*i++;//第四行
  6. System.out.println("i="+i);
  7. System.out.println("j="+j);
  8. System.out.println("k="+k);
  9. }
  10. /**
  11. 结果:
  12. i=4
  13. j=1
  14. k=11
  15. */

分析:

①、第一行:int i=1 ;   

②、第二行:i = i++; 

                    首先 i++ : 然后i=i++  :

③、第三行:int j = i++;

                    首先i++:  然后j=i++;

④、第四行:int k = i+ ++i*i++;

        计算是先算乘除后算加减,但是进入数据栈是从左到右。

         首先是i先进入数据栈:        

         然后是++i自增之后直接进入数据栈:

         之后是i++先进数据栈再自增:

         之后是++i*i++是:3*3:

         之后是i+ ++i*i++是2+9:

        最后是int k = i+ ++i*i++是k=11:

文章来源: blog.csdn.net,作者:轻狂书生FS,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/LookForDream_/article/details/87932898

(完)