随笔- 62  文章- 1  评论- 5  阅读- 13061 

JAVA进阶

1 对象序列化

1.1 对象要序列化要实现Serializable接口

1.2 然后通过ObjectInputStream 对象读入流来读入一个对象

new ObjectOutputStream(new xxOutputStream(""))
new的时候传入一个读入流

1.3 需要申明一个序列化版本号

private static final long serialVersionUID = ;
//用于协商该类的版本,序列化和反序列的版本号不一致时,会异常。修订后应该修改版本号,这样之前序列化的对象进行反序列的时候会失败,抛异常。
//序列化对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(""));
//写入
oos.writeObject();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(""));
//读进
Object o = ois.readObject();

2 打印流

2.1 所用类及方法

类:PrintStream

image-20220814203600118

改变输出语句到文件

PrintStream printStream = new PrintStream("2.txt");
System.out.println("1111");
System.out.println("1111");
System.setOut(printStream);
System.out.println("2222");
System.out.println(2222);

2.2 读取Properties

案例

//写配置文件
Properties properties = new Properties();
properties.setProperty("admin","123456");
//参数一 保存管道,字符输出流管道, 参数二 保存的注解
properties.store(new FileWriter("123.properties"),"");
//加载配置文件
properties.load(new FileInputStream("123.properties"));
String admin = properties.getProperty("admin");
System.out.println(admin);

2.3 commons-io库

封装了常用的IO操作类库 , 提高开发效率

2.3.1 导入依赖

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>

2.3.2 FileUtils作用

image-20220814234424742

2.3.3常用工具类

FileUtils
IOUtils

3 线程

3.1 定义

thread - 一个程序内部的一条执行路径

main方法的执行就是一条单独的执行路径

3.2 三种方式创建多线程

3.2.1 继承Thread类

便于构建, 只需要重写run方法, 但是已经继承了一个类了 ,不利于拓展

3.2.1.1样例
public class ThreadDemo1 {
public static void main(String[] args) {
Thread t = new MyThread();
//调用start方法启用线程
t.start();
for (int i = 0; i < 5; i++) {
System.out.println("主线程"+i);
}
}
}
class MyThread extends Thread{
/**
* 重写run方法
*/
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子线程"+i);
}
}
}

3.2.2 实现Runnable接口

3.2.2.1样例
public class ThreadDemo2 {
public static void main(String[] args) {
//任务对象
Runnable target = new MyRunnable();
//任务交给Thread处理
Thread t = new Thread(target);
t.start();
for (int i = 0; i < 5; i++) {
System.out.println("主线程"+i);
}
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子线程"+i);
}
}
}
使用匿名类实现
new Thread(){
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子1线程"+i);
}
}
}.start();
//使用Runnable
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子2线程"+i);
}
}
}).start();
使用Lambada表达式优化
//条件:需要代替的类是一个接口,且有且仅有一个需要被替代的方法,仅有一个参数省去小括号,仅有一条语句省去大括号
new Thread(()->{
for (int i = 0; i < 5; i++) {
System.out.println("子3线程"+i);
}
}).start();

3.2.3 实现Callable接口 , 结合FutureTask

优点-可以获取返回值

3.2.3.1 样例
public class ThreadDemo3 {
public static void main(String[] args) {
Callable<String> call = new MyCallable(3);
FutureTask<String> f1 = new FutureTask<>(call);
Thread t1 = new Thread(f1);
t1.start();
String s = null;
try {
//线程执行完毕,才会提取结果
s = f1.get();
System.out.println(s);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("...");
}
}
class MyCallable implements Callable<String>{
private int n;
public MyCallable(int n) {
this.n = n;
}
@Override
public String call() throws Exception {
// System.out.println(Thread.getAllStackTraces());
// System.out.println(Thread.activeCount());
// System.out.println(Thread.currentThread().getName());
// Thread.sleep(5000);
return String.valueOf(n+1);
}
}

3.2.4 三种方式对比

image-20220815224712603

3.2.5Thread常用方法

sleep - 静态方法

Thread.currentThread() - 获取当前线程

image-20221009232427303

3.3 加锁

3.3.1 同步代码块 - - synchronized

解决线程同步问题 - 线程安全

idea中 - 选中代码块 快捷键: Ctrl + Alt + T

将代码块放到同步代码块里

synchronized ("hhh") {
System.out.println("aaa");
System.out.println("aaa");
System.out.println("aaa");
}

对于实例方法 使用this作为锁 - 一个账户的调用

synchronized (this) {
System.out.println("aaa");
System.out.println("aaa");
System.out.println("aaa");
}

对于静态方法,使用字节码 类名.class作为锁 - 所有线程一起调用的 所以需要用这个整个类的调用作为锁

synchronized (xx.class) {
System.out.println("aaa");
System.out.println("aaa");
System.out.println("aaa");
}

3.3.2 同步方法

同步方法底层也是有隐式锁的,锁的范围是整个方法的代码

如果方法是实例方法,默认用this作为锁对象

如果是静态方法,默认用类名.class 作为锁对象

public synchronized void xx(){
}

3.3.3 Lock锁

image-20221009234252902

class Account{
//一个实例一把锁
private static Lock lock = new ReentrantLock();
public void doSomeThing(){
lock.lock();//上锁
//一定要保证能够解锁
try{
System.out.println(11);
}finally {
lock.unlock();//解锁
}
}
}
public class LockDemo4 {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
}
}

3.3.4 线程通信

线程间互相发送数据 - 通过共享一个数据

生产者生产数据后,唤醒消费者,等待自己 消费者消费数据后,唤醒生产者,等待自己

(this.notifyAll();this.wait()😉

操作同一个变量的方法应该加上synchronize 变成同步方法 加锁

3.4线程池

设定固定数量的线程- 重复利用这些线程来执行任务

防止资源耗尽

3.4.1 创建线程池

image-20221010131321189

3.4.2 线程池构造器

image-20221010131521595

image-20221010132435672

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class ThreadDemo {
public static void main(String[] args) {
ThreadPoolExecutor pool = new ThreadPoolExecutor(
3,5,6, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(5),new ThreadPoolExecutor.AbortPolicy()
);
MyRunnable target = new MyRunnable();
pool.execute(target);
pool.execute(target);
pool.execute(target);
pool.execute(target);
pool.execute(target);
}
}

任务执行 - 核心线程数+ 任务队列最大数 = 3+5 = 8 线程执行数超过8 , 则会开始在核心线程数3的基础上,创建临时线程

如果执行数量大于线程池的线程数5 + 等待队列大小5 则新开的线程会执行相应的拒绝策略

image-20221010172123832

//核心线程执行
pool.execute(target);
pool.execute(target);
pool.execute(target);
//队列等待
pool.execute(target);
pool.execute(target);
pool.execute(target);
pool.execute(target);
pool.execute(target);
//临时线程可创建 5 - 3 = 2
pool.execute(target);
pool.execute(target);
//多余线程
pool.execute(target);
关闭线程池

线程池在一般状态是不会主动关闭的, 所以主线程执行完并不会停止程序

在任务没执行完时关闭线程池会抛出异常,但是线程池能够关闭

pool.shutdownNow();//强制关闭
pool.shutdown(); //任务执行完 有序关闭

3.4.3 新任务拒绝策略

image-20221010172650752

3.4.4 ExcutorService

image-20221010182128214

3.4.4.1实现执行Callable接口的线程池
class MyCallable implements Callable<String>{
private int n;
public MyCallable(int n) {
this.n = n;
}
@Override
public String call() throws Exception {
// System.out.println(Thread.getAllStackTraces());
// System.out.println(Thread.activeCount());
// System.out.println(Thread.currentThread().getName());
// Thread.sleep(5000);
return String.valueOf(n+1);
}
}
ExecutorService pool = new ThreadPoolExecutor(
3,5,6, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(5),new ThreadPoolExecutor.AbortPolicy()
);
Future<String> f1 = pool.submit(new MyCallable(100));
Future<String> f2 = pool.submit(new MyCallable(200));
Future<String> f3 = pool.submit(new MyCallable(300));
Future<String> f4 = pool.submit(new MyCallable(400));
System.out.println(f1.get());
System.out.println(f2.get());
System.out.println(f3.get());
System.out.println(f4.get());
3.4.4.2Excutors工具类构建线程池

image-20221010184307017

3.5 定时器

Timer定时器

public class TimerDemo {
public static void main(String[] args) {
//定时器本来就是个单线程
Timer timer = new Timer();
//调用方法 处理定时任务
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行");
}
},3000,2000);
}
}

3.5.1 Timer引入多线程--ScheduledExecutorService

ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);
pool.scheduleAtFixedRate(() -> {
System.out.println(111);
},0,10, TimeUnit.SECONDS);

3.6 并发与并行

正在运行的程序就是一个独立的进程 吗, 线程是属于进程的 , 多个线程是并发与并行同时进行的

3.6.1 并发

  • CPU同时处理的线程数量有限
  • CPU会轮询为系统的每个线程服务,由于CPU的切换速度很快(时间片) , 给我们的感觉这些线程在同时执行,这就是并发

同一个核心一个时间点只能执行一个线程 - 执行完这个线程立马切换到下一个线程的任务 -- 并发

3.6.2 并行

n个线程能够同时执行

3.7 线程的生命周期

New - 新建状态

Runnable 可运行状态

Teminated 被终止状态

img

image-20221010221724254

4 网络通信

常见的通信模式为 CS Client-Server 、

Browser/Server

4.1 获取IP对象

public class Network {
public static void main(String[] args) throws IOException {
//获取本地IP地址
// InetAddress IP类
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost.getHostName());
System.out.println(localHost.getHostAddress());
InetAddress ip2 = InetAddress.getByName("www.baidu.com");
System.out.println(ip2.getHostAddress());
System.out.println(ip2.getHostName());
InetAddress ip3 = InetAddress.getByName("163.177.151.109");
System.out.println(ip3.getHostName());
System.out.println(ip3.getHostAddress());
//是否能连通 5s测试
System.out.println(ip3.isReachable(5000));
}
}

4.2 端口类型

image-20221012142033948

4.3 数据包对象

image-20221012163515173

4.4 发送端和接收端对象

image-20221012163534552

image-20221012163549648

4.5 UDP通信 - JAVA实现

4.5.1 接收端

public class NetWork_Server_Demo3 {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket(8888);
byte[] bytes = new byte[1024 * 64];
DatagramPacket packet = new DatagramPacket(bytes, bytes.length);
socket.receive(packet);
int len = packet.getLength();
System.out.println(new String(bytes,0,len));
socket.close();
}
}

4.5.2 发送端

public class NetWork_Client_Demo2 {
public static void main(String[] args) throws IOException {
//创建发送端对象
DatagramSocket socket = new DatagramSocket();
//创建数据包对象
/**
* (byte buf[], int offset, int length,
* InetAddress address, int port) {
*/
byte[] bytes = "sbsbsbsbsbsbbsb".getBytes();
DatagramPacket packet = new DatagramPacket(
bytes,//数据
bytes.length,//发送长度
InetAddress.getLocalHost(),//IP类 目标IP
8888//端口
);
socket.send(packet);
socket.close();
}
}

4.5.3 三种通信方式

4.5.3.1 单播
4.5.3.2 广播

端口一致 发送的IP 255.255.255.255

4.5.3.3组播

image-20221012231241555

MulticastSocket multicastSocket = new MulticastSocket(8888);
//jdk14后废弃
multicastSocket.joinGroup(InetAddress.getByName("224.0.0.1"));
multicastSocket.joinGroup(new
InetSocketAddress("224.0.0.1",8888),
NetworkInterface.getByInetAddress(InetAddress.getLocalHost()));

4.6 TCP通信

4.6.1 客户端

image-20221015120824152

public class NetWork_TCP_Client_Demo4 {
public static void main(String[] args) {
//创建Socket通信管道请求有服务端的连接
try{
Socket socket = new Socket("127.0.0.1", 7777);
OutputStream os = socket.getOutputStream();
PrintStream ps = new PrintStream(os);
ps.println("我是TCP客户端");
// ps.flush();
}catch (Exception e){
e.printStackTrace();
}
}
}

4.6.2 服务端

public class NetWork_TCP_Server_Demo5 {
public static void main(String[] args) {
try {
//注册端口
ServerSocket serverSocket = new ServerSocket(7777);
//等待客户端的socket连接请求,建立通信管道
Socket socket = serverSocket.accept();
//从socket中获取字节输入流
InputStream inputStream = socket.getInputStream();
//包装成字符输入流
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
//读取消息
String msg;
if ((msg=reader.readLine())!=null){
System.out.println("收到 "+socket.getRemoteSocketAddress()+" : "+msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

4.6.3 多发多收 -- 多线程

4.6.3.1 Client
public class NetWork_TCP_Thread_ClientDemo6 {
public static void main(String[] args) {
//创建Socket通信管道请求有服务端的连接
try{
Socket socket = new Socket("127.0.0.1", 7777);
OutputStream os = socket.getOutputStream();
PrintStream ps = new PrintStream(os);
Scanner sc = new Scanner(System.in);
while (true){
System.out.print("请输入:");
String s = sc.nextLine();
ps.println(s);
// ps.flush();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
4.6.3.2 Server -- 开启多线程来接受socket
public class NetWork_TCP_Thread_ServerDemo7 {
public static void main(String[] args) {
try {
//注册端口
ServerSocket serverSocket = new ServerSocket(7777);
while (true){
//等待客户端的socket连接请求,建立通信管道
Socket socket = serverSocket.accept();
new ServerReaderThread(socket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
4.6.3.4 实现接受socket的线程类
public class ServerReaderThread extends Thread{
private Socket socket;
public ServerReaderThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
//从socket中获取字节输入流
InputStream inputStream = socket.getInputStream();
//包装成字符输入流
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
//读取消息
String msg;
while ((msg=reader.readLine())!=null){
System.out.println("收到 "+socket.getRemoteSocketAddress()+" : "+msg);
}
} catch (IOException e) {
System.out.println(socket.getRemoteSocketAddress()+"下线了");
}
}
}

4.6.4使用线程池实现

4.6.4.1 Server
public class NetWork_TCP_Thread_ServerDemo7 {
//使用静态变量记住一个线程池对象
private static ExecutorService pool = new ThreadPoolExecutor(
3,5,6, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(2),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
public static void main(String[] args) {
try {
//注册端口
ServerSocket serverSocket = new ServerSocket(7777);
while (true){
//等待客户端的socket连接请求,建立通信管道
Socket socket = serverSocket.accept();
ServerReaderRunnable target = new ServerReaderRunnable(socket);
pool.execute(target);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
4.6.4.2 Runnable任务类
public class ServerReaderRunnable implements Runnable{
private Socket socket;
public ServerReaderRunnable(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
//从socket中获取字节输入流
InputStream inputStream = socket.getInputStream();
//包装成字符输入流
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
//读取消息
String msg;
while ((msg=reader.readLine())!=null){
System.out.println("收到 "+socket.getRemoteSocketAddress()+" : "+msg);
}
} catch (IOException e) {
System.out.println(socket.getRemoteSocketAddress()+"下线了");
}
}
}

5 反射

image-20221021160851565

5.1 三种获取Class对象的方法

public class GetClass {
public static void main(String[] args) throws ClassNotFoundException {
Class c = Class.forName("com.example.springbootdemo.domain.Author");
System.out.println(c);
Class c1 = Author.class;
Author author = new Author();
Class c3 = author.getClass();
}
}

5.2 获取构造器对象

image-20221021231124520

public class GetClassConsrtructorDemo {
public static void main(String[] args) throws NoSuchMethodException {
Class c = Author.class;
//public的构造器
Constructor[] constructors = c.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor.getParameterCount());
}
//全部构造器
Constructor[] constructors2 = c.getDeclaredConstructors();
for (Constructor constructor : constructors2) {
System.out.println(constructor.getParameterCount());
}
//单个构造器 无参
Constructor constructor1 = c.getConstructor();
System.out.println(constructor1.getParameterCount());
//获取全参构造器, 与构造器的参数的类型一一对应
Constructor constructor2 = c.getConstructor(Long.class, String.class, Integer.class, String.class, List.class);
System.out.println(constructor2.getParameterCount());
}
}

5.3 暴力打开权限,获取私有对象构造器

public class UseClassConstructorDemo {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class c = Author.class;
//无参构造器
Constructor constructors1 = c.getDeclaredConstructor();
//遇到了私有的构造器可以暴力反射
//打开权限 其实是取消权限检查控制, 使private也能被访问到
constructors1.setAccessible(true);
Author author = (Author) constructors1.newInstance();
System.out.println(author);
//获取全参构造器, 与构造器的参数的类型一一对应
Constructor constructor2 = c.getDeclaredConstructor(Long.class, String.class, Integer.class, String.class, List.class);
System.out.println(constructor2.getParameterCount());
}
}

5.4 获取字段

Class c = Author.class;
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
System.out.println(field.getName()+"===>"+field.getType());
}
Field id = c.getDeclaredField("id");
//打开权限
id.setAccessible(true);
Author author = new Author();
//通过反射暴力修改值
id.set(author,111L);
System.out.println(author);
//获取id
Object o = id.get(author);
System.out.println(o);

5.5 反射的作用 绕过编译阶段

image-20221023161903631

public class ReflectDemo {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(3);
Class c = list.getClass();
Method add = c.getMethod("add",Object.class);
Object invoke = add.invoke(list, "我不当人啦!");
System.out.println(Arrays.toString(list.stream().toArray()));
}
}

5.6 反射做通用框架

public class ReflectMybatisUtilDemo {
public static void save(Object o) throws IllegalAccessException, FileNotFoundException {
PrintStream ps = new PrintStream(new FileOutputStream("D:/Springboot/test/data.txt"));
Class c = o.getClass();
ps.println("========"+c.getSimpleName()+"=========");
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
String name = field.getName();
//开启权限
field.setAccessible(true);
String value = field.get(o)+"";
ps.println(name + " = "+value);
}
System.out.println("成功");
}
public static void main(String[] args) {
try {
save(new Book(1,"xxxx123"));
} catch (IllegalAccessException | FileNotFoundException e) {
e.printStackTrace();
}
}
}

7 注解

7.1 定义

image-20221023171049156

7.2 自定义注解

7.2.1 格式

image-20221023171212725

7.2.2 实现

public @interface MyBook {
String name() default "";
String[] authors();
double price();
}

7.2.3 可标注在类 、 方法 、 属性上

@MyBook(name = "《精通JAVASE",authors = {"11","22"},price = 182.0)
public class AnnotationDemo1 {
@MyBook(name = "《精通JAVASE",authors = {"11","22"},price = 182.0)
private AnnotationDemo1(){
}
public static void main(String[] args) {
@MyBook(name = "《精通JAVASE",authors = {"11","22"},price = 182.0)
int age = 1;
}
}

7.3 元注解

image-20221023215217751

image-20221023215458972

@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {
}

7.4 解析注解

image-20221023223331055

@MyBook(name = "类",authors = {"11","22"},price = 182.0)
public class AnnotationDemo1 {
@MyBook(name = "《精通JAVASE",authors = {"11","22"},price = 182.0)
int age = 1;
@MyBook(name = "《精通JAVASE",authors = {"11","22"},price = 182.0)
public AnnotationDemo1(){
}
@MyBook(name = "test方法",authors = {"11","22"},price = 182.0)
public void test(){
}
public static void main(String[] args) throws NoSuchMethodException {
Class c = AnnotationDemo1.class;
Method m = c.getDeclaredMethod("test");
if(m.isAnnotationPresent(MyBook.class)){
MyBook book = (MyBook) m.getDeclaredAnnotation(MyBook.class);
System.out.println(Arrays.toString(book.authors()));
System.out.println(book.price());
System.out.println(book.name());
}
if (c.isAnnotationPresent(MyBook.class)) {
MyBook book =(MyBook) c.getDeclaredAnnotation(MyBook.class);
System.out.println(Arrays.toString(book.authors()));
System.out.println(book.price());
System.out.println(book.name());
}
}
}

7.5 模拟Junit框架

7.5.1 注解类

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface MyTest {
}

7.5.2 解析注解类

public class AnnotationTestDemo {
@MyTest
public void test1(){
System.out.println("test1");
}
public void test2(){
System.out.println("test2");
}
@MyTest
public void test3(){
System.out.println("test3");
}
/**
* 调用有注解的菜单
*/
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
AnnotationTestDemo annotationTestDemo = new AnnotationTestDemo();
Class c = AnnotationTestDemo.class;
Method[] methods = c.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(MyTest.class)){
method.invoke(annotationTestDemo);
}
}
}
}

8 动态代理

8.1 功能类

public interface Skill {
void jump();
void sing();
}
public class Star implements Skill{
private String name;
public Star(String name) {
this.name = name;
}
@Override
public void jump() {
System.out.println("跳舞..");
}
@Override
public void sing() {
System.out.println("唱歌..");
}
}

8.2 代理类

public class StarAgentProxy {
public static Skill getProxy(Star s){
//生成一个代理对象
return (Skill) Proxy.newProxyInstance(
s.getClass().getClassLoader(), //类加载器
s.getClass().getInterfaces(),//需要代理的方法的接口
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("收首付款");
//method - 正在调用的方法对象
Object rs = method.invoke(s, args);
System.out.println("收尾款");
return rs;
}
} //
);
}
}

8.3 测试代理对象

public class Test {
public static void main(String[] args) {
Star s = new Star("xxx");
Skill s2 = StarAgentProxy.getProxy(s);
s2.jump();
s2.sing();
}
}

8.4 业务层对象动态代理 - 类似AOP

8.4.1 动态代理工具类 - 生成代理对象

public class ProxyUtil {
public static UserService getProxy(UserService obj){
return (UserService) Proxy.newProxyInstance(
obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long startTime = System.currentTimeMillis();
Object rs = method.invoke(obj, args);
long endTime = System.currentTimeMillis();
System.out.println(method.getName()+"耗时" + (endTime - startTime) /1000.0 + "s");
return rs;
}
}
);
}
}

8.4.2 改造成泛型 - 为任意类对象进行代理

public static <T> T getProxy(T obj){
return (T)

8.4.3 执行测试

public static void main(String[] args) {
UserService userService2 = ProxyUtil.getProxy(new UserServiceImpl());
userService2.deleteUsers();
userService2.selectUsers();
userService2.login("admin","123456");
}

9 XML

XML是可扩展标记语言的缩写,是一种数据表示格式,可以描述非常复杂的数据结构,常用语传输和存储数据

9.1 XML的几个特点和使用场景

  • 一是纯文本,默认使用UTF-8 而是可嵌套
  • XML存储为文件,则为.xml文件
  • xml使用场景: XML内容经常被当成消息进行网络传输,或者作为配置文件用于存储系统的信息

9.2 解决特定结构冲突

"<" -> &lt
"&" -> &amp
<![CDTA[任意数据]]>

9.3 导入dtd文件对xml的格式进行约束

image-20221025215741716

image-20221025215752362

9.4 Schema约束

.xsd

dtd约束 -> schema(本身是个xml) -> xml

9.5 解析

9.5.1 Dom常见解析文件

image-20221025222012723

9.5.2 解析文件

image-20221028125614692

9.5.3 解析的api

image-20221028170559407

9.5.4 Xpath四大类

image-20221028182246438

10 工厂模式、装饰模式

10.1 工厂模式

用工厂对象来创建对象

public static XX xx(String info){
switch(info){
case "x":
Zz one = new Zz();
one.setXx(1);
one.setYy(2);
return x1;
case "y":
XX one = new Yy();
one.setXx(3);
one.setYy(4);
return x1;
default:
return null;
}
}
  • 工厂的方法可以封装对象的创建细节 (比如线程池中的Excutors)。
  • 实现类与类之间的解耦操作。

10.2 装饰模式

创建一个新类,包装原始类 , 从而在新类中提升原来类的功能

image-20221028183342150

1、定义父类

2、定义原始类 , 继承父类 , 定义功能

3、定义装饰类, 继承父类 , 包装原始类 , 增强功能

 posted on     阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示

目录导航