Junit 注解 类加载器 .动态代理 jdbc 连接池 DButils 事务 Arraylist Linklist hashset 异常 哈希表的数据结构,存储过程 Map Object String Stringbufere File类 文件过滤器_原理分析 flush方法和close方法 序列号冲突问题

时间:2023-03-08 16:08:55
Junit 注解  类加载器 .动态代理 jdbc 连接池  DButils 事务 Arraylist Linklist hashset 异常 哈希表的数据结构,存储过程 Map Object String Stringbufere File类  文件过滤器_原理分析 flush方法和close方法 序列号冲突问题

Junit 注解

3).其它注意事项:

1).@Test运行的方法,不能有形参;

2).@Test运行的方法,不能有返回值;

3).@Test运行的方法,不能是静态方法;

4).在一个类中,可以同时定义多个@Test的测试方法:

a)可以每个方法单独运行(在每个方法上点右键)

b)也可以全部运行(在除测试方法的其它位置右键)

2..类加载器

1).类加载器:当我们执行某个类时,JVM会加载class文件,并产生Class对象。

不同的类,JVM会使用不同的"类加载器"去加载:

2).类加载器的分类:

1).BootstrapClassLoader : 根类加载器:打印:null。用于加载Java类库中的类

2).ExtClassLoader : 扩展类加载器。用于加载:%JDK%/jre/lib/ext目录下的第三方jar包中的类

3).AppClassLoader : 用于加载自定义类的加载器;

3.动态代理

使用动态代理的步骤:

1).自定义"处理类",实现:InvocationHandler(接口)

重写:invoke()方法

内部添加成员属性:Object target;//表示被代理对象;

通过构造方法赋值;

在invoke()方法内,可以添加其它功能,并且调用原方法。

2).要求,所有被代理的类,必须实现相同的接口--Java的动态代理是基于"接口"的。

3).获取动态代理对象:

IPerson p = (IPerson)Proxy.newProxyInstance(被代理类的类加载器对象,

被代理类的所有接口数组,

自定义"处理类"的对象);

p.方法名();

4.02.能够说出注解的作用

1).编译检查:

2).代码分析:

3).编写文档:

5.能够了解自定义注解解析

1).解析:AnnotatedElement(接口)

boolean isAnnotationPresent(Class annotationClass) 当前对象是否有注解

2).依赖于反射机制,动态的获取每个方法对象,然后判断是否有注解,如果有,就执行;

//1.通过反射获取要执行类的Class对象

Class stuClass = Class.forName("cn.itcast.demo05_自定义注解_解析_运行.Student");

//2.创建要执行类的对象

Object obj = stuClass.newInstance();

//3.获取这个类中的所有方法

Method[] methodArray = stuClass.getMethods();

//4.遍历数组,获取每个方法对象

for(Method m : methodArray){

//5.判断每个方法上,是否有:@MyTest注解

boolean flag = m.isAnnotationPresent(MyTest.class);

//6.如果有MyTest,就运行这个方法

if(flag){

//执行方法

m.invoke(obj);

}

}

Day22   jdbc

1.1.1.1 API详解:获得语句执行

String sql = "insert into category(cid,cname) values('c007','分类')";

Statement语句执行者代码:Statement stmt = con.createStatement();

常用方法:

l 执行SQL语句:

n int executeUpdate(String sql); --执行insert update delete语句. (DML语句)

n ResultSet executeQuery(String sql); --执行select语句. (DQL语句)

2.与IO流一样,使用后的东西都需要关闭!关闭的顺序是先得到的后关闭,后得到的先关闭。

rs.close();

stmt.close();

con.close();

l 3.Statement语句执行者和PrepareStatementst预处理对象区别?

n 执行效率: PrepareStatementst效率要比Statement高

n 性能安全: PrepareStatementst防止SQL注入,保证了数据的安全性

因此,实际开发中一般使用PrepareStatementst

Day23 连接池  DButils

l 为什么学习连接池?

连接是很宝贵的资源.而连接对象的创建和销毁是需要耗费时间.有了连接池以后,在服务器初始化的时候就初始化一些连接,将这些连接放到内存中,我们如果要使用,直接从内存中获取.使用完成以后,将连接归还到内存中.从内存中获取和归还连接的效率要远远高于创建和销毁连接的效率(提高性能)

Day24  事务

1.1.1.2 ThreadLocal

java.lang.ThreadLocal 该类提供了线程局部 (thread-local) 变量,用于在当前线程*享数据。ThreadLocal工具类底层就是一个Map,key存放的当前线程,value存放需要共享的数据。

Day19  Arraylist Linklist hashset

A:集合迭代中的转型

a:在使用集合时,我们需要注意以下几点:

l  集合中存储其实都是对象的地址。

l  集合中可以存储基本数值吗?jdk1.5版本以后可以存储了。

因为出现了基本类型包装类,它提供了自动装箱操作(基本类型à对象),这样,集合中的元素就是基本数值的包装类对象。

0. b:存储时提升了Object。取出时要使用元素的特有内容,必须向下转型。

Collection coll = new ArrayList();

coll.add("abc");

coll.add("aabbcc");

coll.add("shitcast");

Iterator it = coll.iterator();

while (it.hasNext()) {

//由于元素被存放进集合后全部被提升为Object类型

//当需要使用子类对象特有方法时,需要向下转型

String str = (String) it.next();

System.out.println(str.length());

}

注意:如果集合中存放的是多个对象,这时进行向下转型会发生类型转换异常。

0.1A:泛型的好处

la:将运行时期的ClassCastException,转移到了编译时期变成了编译失败。

lb:避免了类型强转的麻烦。

0.2:ArrayList集合的自身特点

底层采用的是数组结构

ArrayList al=new ArrayList();//创建了一个长度为0的Object类型数组

al.add("abc");//底层会创建一个长度为10的Object数组 Object[] obj=new Object[10]

//obj[0]="abc"

//如果添加的元素的超过10个,底层会开辟一个1.5*10的长度的新数组

//把原数组中的元素拷贝到新数组,再把最后一个元素添加到新数组中

0.3 b:HashSet的add()方法和contains方法()底层都依赖 hashCode()方法与equals方法()

*1.  迭代器的并发修改异常 java.util.ConcurrentModificationException

*  就是在遍历的过程中,使用了集合方法修改了集合的长度,不允许的

*/    并发修改异常解决办法:

在迭代时,不要使用集合的方法操作元素。

或者通过ListIterator迭代器操作元素是可以的,ListIterator的出现,解决了使用Iterator迭代过程中可能会发生的错误情况。

Day21异常

关于构造方法抛出异常总结

构造函数到底抛出这个NoAgeException是继承Exception呢?还是继承RuntimeException呢?

* a:继承Exception,必须要throws声明,一声明就告知调用者进行捕获,一旦问题处理了调用者的程序会继续执行。

* b:继承RuntimeExcpetion,不需要throws声明的,这时调用是不需要编写捕获代码的,因为调用根本就不知道有问题。

一旦发生NoAgeException,调用者程序会停掉,并有jvm将信息显示到屏幕,让调用者看到问题,修正代码。

数据的存储结构

A:数据的存储结构

a:栈结构:后进先出/先进后出(手枪弹夹) FILO (first in last out)

b:队列结构:先进先出/后进后出(银行排队) FIFO(first in first out)

c:数组结构:

查询快:通过索引快速找到元素

增删慢:每次增删都需要开辟新的数组,将老数组中的元素拷贝到新数组中

开辟新数组耗费资源

d:链表结构

查询慢:每次都需要从链头或者链尾找起

增删快:只需要修改元素记录的下个元素的地址值即可不需要移动大量元素

2.A:ArrayList集合的自身特点

底层采用的是数组结构

ArrayList al=new ArrayList();//创建了一个长度为0的Object类型数组

al.add("abc");//底层会创建一个长度为10的Object数组 Object[] obj=new Object[10]

//obj[0]="abc"

//如果添加的元素的超过10个,底层会开辟一个1.5*10的长度的新数组

//把原数组中的元素拷贝到新数组,再把最后一个元素添加到新数组中

3.哈希表的数据结构

A:哈希表的数据结构:(参见图解)

数组默认16长度

加载因子:表中填入的记录数/哈希表的长度

例如:

加载因子是0.75 代表:

数组中的16个位置,其中存入16*0.75=12个元素

如果在存入第十三个(>12)元素,导致存储链子过长,会降低哈希表的性能,那么此时会扩充哈希表(在哈希),底层会开辟一个长度为原长度2倍的数组,把老元素拷贝到新数组中,再把新元素添加数组中

当存入元素数量>哈希表长度*加载因子,就要扩容,因此加载因子决定扩容时机

  1. 哈希表的存储过程

存取原理:

每存入一个新的元素都要走以下三步:

1.首先调用本类的hashCode()方法算出哈希值

2.在容器中找是否与新元素哈希值相同的老元素,

如果没有直接存入

如果有转到第三步

3.新元素会与该索引位置下的老元素利用equals方法一一对比

一旦新元素.equals(老元素)返回true,停止对比,说明重复,不再存入

如果与该索引位置下的老元素都通过equals方法对比返回false,说明没有重复,存入

       Day20Map

注意:Map集合不能直接使用迭代器或者foreach进行遍历。但是转成Set之后就可以使用了。

Day15Object String Stringbufere

c: ==号和equals方法的区别

* ==是一个比较运算符号,既可以比较基本数据类型,也可以比较引用数据类型,基本数据类型比较的是值,引用数据类型比较的是地址值

* equals方法是一个方法,只能比较引用数据类型,所有的对象都会继承Object类中的方法,如果没有重写Object类中的equals方法,

equals方法和==号比较引用数据类型无区别,重写后的equals方法比较的是对象中的属性

2. 为什么要重写toString方法

* toString方法返回该对象的字符串表示,其实该字符串内容就是对象的类型+@+内存地址值。

* 由于toString方法返回的结果是内存地址,而在开发中,经常需要按照对象的属性得到相应的字符串表现形式,因此也需要重写它。

3* String s3 = "abc";

* 在内存中只有一个对象。这个对象在字符串常量池中

n * String s4 = new String("abc");

* 在内存中有两个对象。一个new的对象在堆中,一个字符串本身对象,在字符串常量池中

4. A:StringBuffer类概述

* 通过JDK提供的API,查看StringBuffer类的说明

* 线程安全的可变字符序列

* 底层采用字符数组实现,初始容量为16

* B:StringBuffer和String的区别

* String是一个不可变的字符序列

* StringBuffer是一个可变的字符序列

Day14

B: 不能同时使用的修饰符

同时,abstract与private不能同时使用;

同时,abstract与static不能同时使用;

同时,abstract与final不能同时使用。

l C: 修饰类能够使用的修饰符:

修饰类只能使用public、默认的、final、abstract关键字

使用最多的是 public关键字

Day22

//File类静态成员变量

//与系统有关的路径分隔符

String separator = File.pathSeparator;

System.out.println(separator);// 是一个分号,目录的分割(window中环境变量配置各个路径用分号分割,表示一个完整的路径结束)  Linux中是冒号 :

//与系统有关的默认名称分隔符

separator = File.separator;

System.out.println(separator);// 向右 \  目录名称分割  Linux /

}

2.

###14文件过滤器_原理分析

* A:文件过滤器_原理分析

* listFiles()遍历目录的同时,获取到了文件名全路径,调用过滤器的方法accept,将获取到的路径传递给accept方法的参数pathname

* accept方法接收了参数pathname,参数是listFiles传递来的

* 在accept方法中,进行判断,如果这个路径是Java文件,返回true,走着返回false

* 一旦方法返回了true

* listFiles将路径保存到File数组中

A: 递归遍历全目录

* a: 案例代码

/*

*  对一个目录的下的所有内容,进行完全的遍历

*  编程技巧,方法的递归调用,自己调用自己

2.递归概念和注意事项

* A:递归概念和注意事项

* a: 递归概念

* 递归,指在当前方法内调用自己的这种现象

* 递归分为两种,直接递归和间接递归

* 直接递归称为方法自身调用自己。间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法

* b: 注意事项

* 递归一定要有出口, 必须可以让程序停下

* 递归次数不能过多

* 构造方法,禁止递归

Day23

flush方法和close方法区别

* A: flush方法和close方法区别

*a: flush()方法

* 用来刷新缓冲区的,刷新后可以再次写出,只有字符流才需要刷新

*b: close()方法

* 用来关闭流释放资源的的,如果是带缓冲区的流对象的close()方法,不但会关闭流,还会再关闭流之前刷新缓冲区,关闭后不能再写出

08静态不能序列化

* A: 静态不能序列化

* a: 原因

* 序列化是把对象数据进行持久化存储

* 静态的东西不属于对象,而属于类

###09transient关键字

* A: transient关键字

* a: 作用

* 被transient修饰的属性不会被序列化

* transient关键字只能修饰成员变量

###10Serializable接口的含义

* A:Serializable接口的含义

* a: 作用

* 给需要序列化的类上加标记。该标记中没有任何抽象方法

* 只有实现了 Serializable接口的类的对象才能被序列化

###11序列化中的序列号冲突问题

* A: 序列化中的序列号冲突问题

* a: 问题产生原因

* 当一个类实现Serializable接口后,创建对象并将对象写入文件,之后更改了源代码(比如:将成员变量的修饰符有private改成public),

再次从文件中读取对象时会报异常

.序列化流_输出流_ObjectOutputStream

1.序列化:程序可以将一个"对象--包括属性的值"整体的存入到一个文件中,或者将这个对象通过网络传输,

这个过程就叫:序列化。

反序列化:将之前序列化的对象从文件或者网络中恢复到程序中,这个过程叫:反序列化。

2.构造方法:

ObjectOutputStream(OutputStream out) 创建写入指定 OutputStream 的 ObjectOutputStream

3.序列化的方法:

public final void writeObject(Object obj):可以将一个对象存储到文件中。

注意:要被序列化的类,必须实现:java.io.Serializable(接口)

这种接口没有任何方法,属于"标记"性接口,实现接口后,表示具有了可以被序列化的功能。

Properties工具类,本质上是一个:Map集合,但有一些方法可以和IO流结合,可以很方便的读写配置文件信息;

load(Reader in):从配置文件中读取信息

store(Writer out):向配置文件写入信息