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

改变输出语句到文件

 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作用

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 三种方式对比

3.2.5Thread常用方法

sleep - 静态方法

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

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锁

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 创建线程池

3.4.2 线程池构造器

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 则新开的线程会执行相应的拒绝策略

     	//核心线程执行
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 新任务拒绝策略

3.4.4 ExcutorService

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工具类构建线程池

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 被终止状态

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 端口类型

4.3 数据包对象

4.4 发送端和接收端对象

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组播

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 客户端

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 反射

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 获取构造器对象

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 反射的作用 绕过编译阶段

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 定义

7.2 自定义注解

7.2.1 格式

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 元注解

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

7.4 解析注解

@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的格式进行约束

9.4 Schema约束

.xsd

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

9.5 解析

9.5.1 Dom常见解析文件

9.5.2 解析文件

9.5.3 解析的api

9.5.4 Xpath四大类

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 装饰模式

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

1、定义父类

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

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

Java基础进阶内容 - 随笔的更多相关文章

  1. 第二十八节:Java基础-进阶继承,抽象类,接口

    前言 Java基础-进阶继承,抽象类,接口 进阶继承 class Stu { int age = 1; } class Stuo extends Stu { int agee = 2; } class ...

  2. Java基础进阶

    Java基础进阶J Object类 hashcode() toString() clone() getClass() notify() wait() equals() Random类 生成 随机数 U ...

  3. Java基础进阶整理

    Java学习笔记整理 本文档是我个人整理的,首先是想通过完成本文档更加扎实自己的基础加强对java语言的理解,然后就是想给入了门的同志们做下贡献. 当然,本文档主要是对java语言基础(当然还有很多基 ...

  4. java基础进阶二:HashMap实现原理分析

    HashMap实现原理分析 1. HashMap的数据结构 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端. 数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二 ...

  5. object - c 语言基础 进阶笔记 随笔笔记

    重点知识Engadget(瘾科技)StackOverFlow(栈溢出)Code4Apprespon魏先宇的程序人生第一周快捷键: Alt+上方向键 跳到最上面  Alt+下方向键 跳到最下面      ...

  6. Java基础进阶:多态与接口重点摘要,类和接口,接口特点,接口详解,多态详解,多态中的成员访问特点,多态的好处和弊端,多态的转型,多态存在的问题,附重难点,代码实现源码,课堂笔记,课后扩展及答案

    多态与接口重点摘要 接口特点: 接口用interface修饰 interface 接口名{} 类实现接口用implements表示 class 类名 implements接口名{} 接口不能实例化,可 ...

  7. java基础进阶:SQL的运用

    SQL的基础的运用 /* --1.学生表 Student(S,Sname,Sage,Ssex) --S 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 --2.课程表 Cour ...

  8. java基础进阶一:String源码和String常量池

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/8046564.html 邮箱:moyi@moyib ...

  9. 笔记-迎难而上之Java基础进阶8

    函数式接口 函数式接口:有且只有一个抽象方法的接口,(可以包含其他默认,静态,私有方法) //函数式接口的使用,创建一个函数式接口 public interface FunctionalInterfa ...

  10. 笔记-迎难而上之Java基础进阶6

    import java.io.*; public class InputStreamDemo{ public static void main(String[] args) throws IOExce ...

随机推荐

  1. Java 并发线程池线程数配置

    1. 如果任务是计算密集型的,线程池大小建议设置为Ncpu + 1 其中N是CPU数量, +1 是为了在某一个线程处于暂停阶段时,有新的线程可以用来执行,减少CPU中断时间. 2. 如果是IO密集型, ...

  2. 蓝桥杯训练赛二-问题 B

    字符串的输入输出处理. 输入 第一行是一个正整数N,最大为100.之后是多行字符串(行数大于N), 每一行字符串可能含有空格,字符数不超过1000. 输出 先将输入中的前N行字符串(可能含有空格)原样 ...

  3. pip安装清华源

    一.更换PIP源PIP源在国外,速度慢,可以更换为国内源,以下是国内一些常用的PIP源. 豆瓣(douban) http://pypi.douban.com/simple/ (推荐)清华大学 http ...

  4. 看K线学炒股(8.9)

    今天是食品饮料类题材大涨的一天,相应板块涨了6个多点,看着真是诱人.我以前关注的两只股票:海天味业和三全食品,今天都大涨.三全食品接近涨停.这种票容易选出来但也很难拿住.比如前些天买入了,结果8.5的 ...

  5. Idea下载指南之几个选项

    通常我们在下载idea等一些图形编译器时,都会有很多选项供您选择,下面我们来看下这几个英文选项吧. create desktop Shortcut Update Path variable(resta ...

  6. 计数 dp 部分例题(一~五部分)

    一.状态设计和简化(状態をまとめる) 例题1:Unhappy Hacking 题意 有一个空串,可以进行下面三种操作: 在末尾加入一个 \(0\). 在末尾加入一个 \(1\). 删去末尾的数,如果串 ...

  7. JS学习-setTimeout()

    setTimeout() 超时限制-节流 /* interval(),在setInterval()时间间隔到期后调用. * timeout()setTimeout()计时器到期后调用. * run() ...

  8. Unity中的批处理优化与GPU Instancing【转】

    我们都希望能够在场景中投入一百万个物体,不幸的是,渲染和管理大量的游戏对象是以牺牲CPU和GPU性能为代价的,因为有太多Draw Call的问题,最后我们必须找到其他的解决方案.在本文中,我们将讨论两 ...

  9. 上传文件-jq

    var formFile = new FormData(); formFile.append("[file]", fileObj); formFile.append("t ...

  10. jadx 定位方法

    目录 链接参数定位 链接参数定位 通过搜索请求链接中的参数来定位函数位置,如下图所示,请求链接为 https://www.python-spider.com/api/app1,app1为链接标识,可以 ...