Java基础进阶内容 - 随笔
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 解决特定结构冲突
"<" -> <
"&" -> &
<![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基础进阶内容 - 随笔的更多相关文章
- 第二十八节:Java基础-进阶继承,抽象类,接口
前言 Java基础-进阶继承,抽象类,接口 进阶继承 class Stu { int age = 1; } class Stuo extends Stu { int agee = 2; } class ...
- Java基础进阶
Java基础进阶J Object类 hashcode() toString() clone() getClass() notify() wait() equals() Random类 生成 随机数 U ...
- Java基础进阶整理
Java学习笔记整理 本文档是我个人整理的,首先是想通过完成本文档更加扎实自己的基础加强对java语言的理解,然后就是想给入了门的同志们做下贡献. 当然,本文档主要是对java语言基础(当然还有很多基 ...
- java基础进阶二:HashMap实现原理分析
HashMap实现原理分析 1. HashMap的数据结构 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端. 数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二 ...
- object - c 语言基础 进阶笔记 随笔笔记
重点知识Engadget(瘾科技)StackOverFlow(栈溢出)Code4Apprespon魏先宇的程序人生第一周快捷键: Alt+上方向键 跳到最上面 Alt+下方向键 跳到最下面 ...
- Java基础进阶:多态与接口重点摘要,类和接口,接口特点,接口详解,多态详解,多态中的成员访问特点,多态的好处和弊端,多态的转型,多态存在的问题,附重难点,代码实现源码,课堂笔记,课后扩展及答案
多态与接口重点摘要 接口特点: 接口用interface修饰 interface 接口名{} 类实现接口用implements表示 class 类名 implements接口名{} 接口不能实例化,可 ...
- java基础进阶:SQL的运用
SQL的基础的运用 /* --1.学生表 Student(S,Sname,Sage,Ssex) --S 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 --2.课程表 Cour ...
- java基础进阶一:String源码和String常量池
作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/8046564.html 邮箱:moyi@moyib ...
- 笔记-迎难而上之Java基础进阶8
函数式接口 函数式接口:有且只有一个抽象方法的接口,(可以包含其他默认,静态,私有方法) //函数式接口的使用,创建一个函数式接口 public interface FunctionalInterfa ...
- 笔记-迎难而上之Java基础进阶6
import java.io.*; public class InputStreamDemo{ public static void main(String[] args) throws IOExce ...
随机推荐
- Java 并发线程池线程数配置
1. 如果任务是计算密集型的,线程池大小建议设置为Ncpu + 1 其中N是CPU数量, +1 是为了在某一个线程处于暂停阶段时,有新的线程可以用来执行,减少CPU中断时间. 2. 如果是IO密集型, ...
- 蓝桥杯训练赛二-问题 B
字符串的输入输出处理. 输入 第一行是一个正整数N,最大为100.之后是多行字符串(行数大于N), 每一行字符串可能含有空格,字符数不超过1000. 输出 先将输入中的前N行字符串(可能含有空格)原样 ...
- pip安装清华源
一.更换PIP源PIP源在国外,速度慢,可以更换为国内源,以下是国内一些常用的PIP源. 豆瓣(douban) http://pypi.douban.com/simple/ (推荐)清华大学 http ...
- 看K线学炒股(8.9)
今天是食品饮料类题材大涨的一天,相应板块涨了6个多点,看着真是诱人.我以前关注的两只股票:海天味业和三全食品,今天都大涨.三全食品接近涨停.这种票容易选出来但也很难拿住.比如前些天买入了,结果8.5的 ...
- Idea下载指南之几个选项
通常我们在下载idea等一些图形编译器时,都会有很多选项供您选择,下面我们来看下这几个英文选项吧. create desktop Shortcut Update Path variable(resta ...
- 计数 dp 部分例题(一~五部分)
一.状态设计和简化(状態をまとめる) 例题1:Unhappy Hacking 题意 有一个空串,可以进行下面三种操作: 在末尾加入一个 \(0\). 在末尾加入一个 \(1\). 删去末尾的数,如果串 ...
- JS学习-setTimeout()
setTimeout() 超时限制-节流 /* interval(),在setInterval()时间间隔到期后调用. * timeout()setTimeout()计时器到期后调用. * run() ...
- Unity中的批处理优化与GPU Instancing【转】
我们都希望能够在场景中投入一百万个物体,不幸的是,渲染和管理大量的游戏对象是以牺牲CPU和GPU性能为代价的,因为有太多Draw Call的问题,最后我们必须找到其他的解决方案.在本文中,我们将讨论两 ...
- 上传文件-jq
var formFile = new FormData(); formFile.append("[file]", fileObj); formFile.append("t ...
- jadx 定位方法
目录 链接参数定位 链接参数定位 通过搜索请求链接中的参数来定位函数位置,如下图所示,请求链接为 https://www.python-spider.com/api/app1,app1为链接标识,可以 ...