Java类和实例的初始化、方法的参数传递机制、递归与迭代、成员变量和局部变量、Spring(Bean作用域、支持的事务传播属性和事务隔离级别)、Spring MVC(解决乱码、工作流程) 您所在的位置:网站首页 对象初始化方法演示 Java类和实例的初始化、方法的参数传递机制、递归与迭代、成员变量和局部变量、Spring(Bean作用域、支持的事务传播属性和事务隔离级别)、Spring MVC(解决乱码、工作流程)

Java类和实例的初始化、方法的参数传递机制、递归与迭代、成员变量和局部变量、Spring(Bean作用域、支持的事务传播属性和事务隔离级别)、Spring MVC(解决乱码、工作流程)

2024-07-14 16:12| 来源: 网络整理| 查看: 265

文章目录 Java基础Java类、实例的初始化1. 类初始化2. 实例初始化 方法的参数传递机制递归与迭代1. 递归2. 迭代循环 成员变量和局部变量1. 区别2. 代码 SpringSpring Bean的作用域Spring 支持的事务传播属性和事务隔离级别事务传播属性事务隔离级别 Spring MVCSpring MVC的post请求如何解决中文乱码Spring MVC的get请求如何解决中文乱码简述Spring MVC的工作流程

Java基础 Java类、实例的初始化 1. 类初始化

规则:

一个类要创建实例必须先初始化该类;main方法所在的类总是要先加载和初始化;子类要初始化必须先初始化父类;一个类的初始化就是执行 方法,该方法由 静类变量显示赋值代码 和 静态代码块 组成,这两部分的执行顺序是:谁在前面谁先执行;该方法只执行一次;

代码演示:

父类 public class Father { // 父类静态变量赋值 private static int j = method(); static { System.out.println("父类静态代码块"); } public static int method(){ System.out.println("父类静态常量显示赋值代码"); return 1; } } 子类 public class Son extends Father{ // 子类静态变量赋值 private static int j = method(); static { System.out.println("子类静态代码块"); } public static int method(){ System.out.println("子类静态变量显示赋值代码"); return 1; } // main方法 public static void main(String[] args) { } } 结果:执行main方法 在这里插入图片描述 2. 实例初始化

规则:

实例初始化就是执行 方法; 方法首行是 super(),即对应父类的 方法;(最先执行) 方法可能重载多个,几个构造器就有几个该方法; 方法由 非静类变量显示赋值代码 、非静态代码块、对应构造器代码组成;三部分执行顺序:非静类变量显示赋值代码 、非静态代码块按先后顺序执行,对应构造器代码最后执行;每次实例化,调用对应构造器,就是执行 方法,子类构造器中一定会调用父类构造器;

注意:

哪些方法不能被重写? final方法、静态方法、private等子类中不可见方法子类如果重写了父类的方法,则调用的一定是子类重写后的方法;非静态方法默认的调用对象是 this;this 对象在 方法中就是正在创建的对象 父类 public class Father { private int i = test(); private static int j = method(); static { System.out.println("父类静态代码块"); } Father(){ System.out.println("父类空参构造器"); } { System.out.println("父类非静态代码块"); } public int test(){ System.out.println("父类的test方法"); return 1; } public static int method(){ System.out.println("父类静态常量显示赋值代码"); return 1; } } 子类 public class Son extends Father{ private int i = test(); private static int j = method(); static { System.out.println("子类静态代码块"); } Son(){ super(); // super() 写不写都存在 System.out.println("子类空参构造器"); } { System.out.println("子类非静态代码块"); } public int test(){ System.out.println("子类重写父类的test方法"); return 1; } public static int method(){ System.out.println("子类静态变量显示赋值代码"); return 1; } public static void main(String[] args) { System.out.println("===第一个实例化==="); Son s1 = new Son(); System.out.println("===第二个实例化==="); Son s2 = new Son(); } }

结果: 在这里插入图片描述 分析:

main方法在子类; 1. 先执行类初始化的代码;方法 2. 执行 方法: 1)子类中的super(); 2)super()即Son的父类Father; 3)执行父类中的非静类变量显示赋值代码:i = test(); 结果应该是:"父类的test方法", 但由于子类重写了父类的test方法所以结果是:"子类重写父类的test方法"; 4)执行父类的非静态代码块; 5)执行父类的构造器; 6)super()执行完,接着执行子类中的非静类变量显示赋值代码:int i = test();非静态代码块; 7)最后执行子类的构造器; 8)第二个实例初始化,即执行两次上面的步骤。 方法的参数传递机制

实参给形参赋值:

是基本数据类型,传递数值;(byte、boolean、short、char、int、float、long、double)是引用数据类型:传递地址值,特殊引用类型不可变性(String、Integer) 代码: 在这里插入图片描述结果: 在这里插入图片描述分析: 执行change方法方法前 在这里插入图片描述 执行change方法后:只有数组和MyData类的成员变量改变了 在这里插入图片描述 递归与迭代

问题:有n阶台阶,一次只能上1阶或者2阶,一共有多少种上法?

1. 递归

思路:设台阶数为n

n=1 跨一步 f(1)=1 n=2 跨一步,再跨一步 直接跨两步 f(2)=2 n=3 先到达f(1),然后从f(1)直接跨两步 先到达f(2),然后从f(2)跨一步 f(3)=f(1)+f(2) n=4 先到达f(2),然后从f(2)直接跨两步 先到达f(3),然后从f(3)跨一步 f(4)=f(2)+f(3) n=x 先到达f(x-2),然后从f(x-2)直接跨两步 先到达f(x-1),然后从f(x-1)跨一步 f(x)=f(x-1)+f(x-2)

代码实现:

public class RecursionDemo { public static void main(String[] args) { long start = System.currentTimeMillis(); int steps = steps(40); long end = System.currentTimeMillis(); System.out.println("共有" + steps + "种方法"); System.out.println("耗时" + (end-start) + "毫秒"); // 耗时358毫秒 } public static int steps(int n) { if (n return n; } return steps(n-1) + steps(n-2); } }

优点:将大问题拆分成小问题,简化代码,阅读性好; 缺点:递归调用浪费空间,调用太多容易造成堆栈溢出;

2. 迭代循环

思路:设台阶数为n,设置两个变量,一个(one)用来存放最后只跨一步这种情况前面的所有方法数,另一个(two)用来存放最后直接跨两步前面的所有方法数;

n=1 跨一步 f(1)=1 n=2 跨一步,再跨一步 直接跨两步 f(2)=2 n=3 先到达f(1),然后从f(1)直接跨两步 f(3)=two+one 先到达f(2),然后从f(2)跨一步 f(3)=f(1)+f(2) n=4 先到达f(2),然后从f(2)直接跨两步 f(3)=two+one 先到达f(3),然后从f(3)跨一步 f(4)=f(2)+f(3) n=x 先到达f(x-2),然后从f(x-2)直接跨两步 f(3)=two+one 先到达f(x-1),然后从f(x-1)跨一步 f(x)=f(x-2)+f(x-1)

代码:

public class RecursionDemo { public static void main(String[] args) { long start = System.currentTimeMillis(); int steps = steps(40); long end = System.currentTimeMillis(); System.out.println("共有" + steps + "种方法"); System.out.println("耗时" + (end - start) + "毫秒"); //耗时0毫秒 } public static int steps(int n) { if (n return n; } int one = 2; // 初始化走到第二阶台的走法 int two = 1; // 初始化走到第一阶台的走法 int sum = 0; // 初始化走法总数 for (int i = 3; i static int s; // 类变量: s int i; // 实例变量: i int j; // 实例变量: j { int i = 1; // 局部变量:i i++; j++; s++; } public void test (int j) { // 局部变量:j (形参) i++; j++; s++; } public static void main(String[] args) { // 局部变量:args (形参) VariableTest v1 = new VariableTest(); // 局部变量:v1 VariableTest v2 = new VariableTest(); // 局部变量:v2 v1.test(10); v1.test(20); v2.test(30); System.out.println("i=" + v1.i + "," + "j=" + v1.j + "," + "s=" + v1.s); System.out.println("i=" + v2.i + "," + "j=" + v2.j + "," + "s=" + v2.s); } }

结果: 在这里插入图片描述 分析: 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

注意: 局部变量与实例变量重名时:在实例变量前加 “this”; 局部变量与类变量重名时:在类变量前加 “类名.” Spring Spring Bean的作用域

在 元素 的 scope 属性里设置bean的作用域,来决定这个bean是单实例还是多实例,默认Spring为每个在 IOC容器里声明的 bean 创建唯一的一个实例,后面使用 getBean() 调用和 bean 引用就会返回唯一的实例,该作用域称为singleton,也是Spring 所有 bean 默认的作用域。

1. singleton(默认作用域) 当IOC容器一创建,就会创建 bean 的实例,而且是单例,每次得到的是同一个; 2. prototype 当IOC容器创建时,不会创建 bean 的实例,每次调用 getBean()方法时,就会创建一个该 bean 的实例; 下面的两个是在 web 环境下: 3. request 每次请求会实例化 bean 4. session 每次会话共享一个 bean Spring 支持的事务传播属性和事务隔离级别 事务传播属性

事务传播行为:一个方法运行在了一个开启了事务的方法中,当前方法使用原来的事务还是开启新的事务

事务的默认属性:propagation=Propagation.REQUIRED @Transactional

情景:买书的方法在同一个事务中,共有100元,book1价值70元,book2价值50元,依次购买,买完book1后发现钱不够支持买book2了,此时事务回滚,两次购买均失败。

将事务挂起,开启新事物 Propagation.REQUIRES_NEW @Transactional(propagation=Propagation.REQUIRES_NEW)

情景:买书的方法在同一个事务中,共有100元,book1价值70元,book2价值50元,依次购买,买完book1后发现钱不够支持买book2了,但是开启了新的事务,成功购买book1。

事务隔离级别 数据库事务并发问题: 有两个事务 Transactional1、Transactional2 脏读:其他事务读取到了另一个事务更新但没有提交成功的数据; 如:在 Transactional1 中将 age 的值从20修改为30,Transactional2 读取到了 Transactional1 修改的值 30 ,此时 Transactional1 回滚,Transactional2 读取的30就是一个无效的值;不可重读读性 如:Transactional1中的age为20,Transactional2将age改为了30并提交,Transactional1再读取age就是30而不是20;幻读 如:Transactional1读取某个表中的部分数据,Transactional2向该表插入新的行,Transactional1再去读取时发现多了新的行。隔离级别 isolation=Isolation. 1. 读未提交:READ UNCOMMITTED:允许Transactional1 读取Transactional2修改未提交的数据;不能解决脏读、不可重复读、幻读。 2. 读已提交:READ COMMITTED:要求Transactional1 只能读取Transactional2 提交的数据;可以解决脏读,不解决不可重复读、幻读。 3. 可重复读:REPEATABLE READ:Transactional1 执行期间,禁止其他事务对当前操作的字段进行修改;可以解决脏读、不可重复读、不解决幻读。 4. 序列化:SERIALIZABLE:Transactional1 执行期间 ,禁止其他事务对这个表进行修改,删除,增加操作;都可以解决。 注意: 不是隔离级别越高越好,级别越高数据一致性更好,但并发性越弱;MySQL四种隔离级别都支持,默认为:可重复读(REPEATABLE READ) Spring MVC Spring MVC的post请求如何解决中文乱码

Spring MVC提供了一个过滤器:CharacterEncodingFilter 在 web.xml中配置即可:

CharacterEncodingFilter org.springframework.web.filter.CharacterEncodingFilter encoding utf-8 CharacterEncodingFilter /* Spring MVC的get请求如何解决中文乱码

在服务器的 server.xml 配置文件中:添加URIEncoding=“UTF-8”

简述Spring MVC的工作流程

在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有