9.16 第1天
static
1.静态的只能访问静态的
2.子类的构造函数中默认调用父类的无参构造函数,只不过第一行代码:super();一直被省略了
3.如果子类的构造函数在第一行super(args1,args2…);调用了父类的其他有参构造函数,那么子类的该构造函数不会再调用父类的默认构造函数
4.方法的三要素:返回值,方法名,参数列表
5.方法签名(method signature) 方法名+参数列表
6.inherit m继承
final
1.修饰类:该类不能被继承(不能有子类,但是可以有父类)
2.修饰方法:该方法不能被重写
3.修饰变量:表明该变量是一个常量,不能再次赋值,正常跟public搭配使用
3.1变量是基本类型:数据值不能发生改变
3.2变量是引用类型:地址值不能发生改变,内容是可以发生改变的
单词
multiple 多个
inherit 继承
modifier 修饰符
assign 赋值
call 调用
9.17 第2天
toString方法
每个类都有这个方法,重写的话方便打印
Polymorphic 多态
1.方法是有多态性的
2.属性没有多态性
异常:
1 .数组索引越界
2. 算术异常 ArithmeticException
3.类型转换异常 CLassCastException
intence 实例 对象 instanceof xx是xx的实例
抽象类:一个类如果不需要创建对象,它的存在仅仅是用来被继承,从而实现代码的复用和多态,那么这个类应该被设计成抽象的
这个类不能被实例化
这个类的方法不需要方法体,只是用来被重写的,称为抽象方法,子类需要重写抽象类的所有抽象方法
注意:含抽象方法的一定是抽象类,抽象类不一定有抽象方法
redundant 多余的
接口:(标准,规范)
1.一种特殊的抽象类
2.接口中只能有常量跟抽象方法
3.方法可以省略abstract,默认抽象方法,成员变量默认public static final
4.接口中可以定义默认方法default(java8),静态方法 static(java8),私有方法 private(java9)
注意:接口可以多实现,类与接口之间叫实现,接口与接口之间叫继承,接口之间可以多继承
接口相当于标准与规范,一个类实现了接口,代表遵循了此规范,那么接口的方法一定要在类里面全部实现
接口的主要作用:
1.解决单继承的问题
2.制定规范
3.接口还有一个标记性作用,只有接口名,没有任何方法
4.定义常量类(常量接口)
9.19 第3天
匿名内部类Sing sing = new Sing(){ public void sing(){}}
lambda: () -> {} 箭头前为参数,箭头后为返回值(方法体)
java为什么引进lamda表达式 原因之一:因其简洁的写法用来取代匿名内部类
Sing sing = () -> {};
匿名内部类与lambda区别
1.一个是类 一个是方法(代表接口中的方法)
2.使用前提不一样 ,lambda的使用前提,一个接口只能有一个方法
jdk8之后 为了引入lambda表达式,大部分接口只有一个方法
lambda省略模式:
1.参数类型可以省略
2.如果参数只有一个,小括号可以省略
3.代码块中只有一条语句,可以省略大括号,如果有return,return也要省略
例:Sing sing = s ->System.out.println();
参考:https://blog.csdn.net/m0_64210833/article/details/123742887
构造方法引用:当构造器的参数列表与函数的参数列表一致时,可以使用此特性,使用方式:类名::new
总结:返回值是当前类,参数列表一致,才能引用
普通方法的引用:lambda方法体内只有一条语句,并且这条语句是在调用某个对象里的方法
方法的参数列表,返回值,与接口的参数以及返回值保持一致
闭包:lambda访问外部变量会自动加上final(不可变)
如何解决:将基本数据类型变成引用数据类型
lambda可以当作参数传递
9.20 第4天
String API 成员方法
equals() 判断两个字符串是否相等
toUpperCase()转大写
toLowerCase()转小写
contains() 判断一个字符串是否包含另一个字符串
equalsIgnoreCase() 忽略大小写进行对比
isEmpty() 判断是否为空(长度为0)
isBlank()只包含空格
startsWith()判断是否以什么开头
endsWith()判断以什么结尾
trim()移除字符串两边空格
concat() 合并字符串
————静态方法—————
valueOf() 基本类型转字符串
————StringBuilder———-
append() 字符串拼接
———System系统相关的工具类——-
long l = System.currentTimeMillis() 当前时间戳 毫秒时间戳
native 没有方法体,由c或者c++实现
arrayCopy() 数组拷贝
System.exit(0) 退出虚拟机运行
System.gc() 垃圾回收 gc=garbage collection
————Math————
abc() 绝对值
round() 四舍五入
ceil() 最近的一个大的整数
floor() 最近的一个小的整数
max()最大值
min()最小值
pow()次方
double d = Math.randow()随机数
————-Object————-
toString()
equals() 不重写默认比较地址
————-Objects———- s结尾大概率是工具类
toString
isNull 判空,程序员基本素养
nonNull
—————-—bigDecimal———————
1.用来解决双精度double大的问题, 作用:用于精确计算以及控制小数位
2.传递字符串可以实现精确计算
a.divide(b,1,BigDecimal.ROUND_UP);
b被除数,1,保留小数点位数,BigDecimal.ROUND_UP 舍入远离零的舍入模式
ROUND_DOWN 直接舍去对应位数后面的数字
add substract multiply divide 加减乘除
基本数据类型包装类
Java共有8中基本数据类型:byte、boolean、char、short、int、float、long、double
对应的包装类分别为:Byte、Boolean、Character、Short、Integer,Float,Long,Double
自动装箱 拆箱
String.valueOf(1); 基本转string
int i = Integer.parseInt(“1”); string转基本
Integer i = Integer.valueOf(“”1) String转包装
NumberFormatException 数值转换异常
比较大小时valueOf保存了[-128,127] 超过该范围不能比较
a.compareTo(b) : a=b 返回0,a>b返回1,a<b返回-1
9.22 第5天
1.冒泡排序
2.二分查找
Arrays.sort(数组对象) 数组排序
Arrays.binarySearch(数组对象,要查找的值) 二分查找
递归:方法调用其本身
异常
异常处理流程:
虚拟机自动处理异常流程:
1.首先判断有没有手动处理
2.发生异常创建异常对象
3.打印异常信息到控制台
4.终端程序运行
手动处理异常
1.throws声明异常:使用在方法定义上,可以声明多个,如果声明了编译异常,方法调用者也要声明
2.throw抛出异常: throw具有return作用,可以查看异常具体信息。自定义异常
3.当一个方法具有返回值,不知道return哪个具体值,应该抛出一个异常对象
5.抛出编译异常,需要在方法头部声明异常
try … catch 捕获异常
可以捕获不同的异常分开处理
特点:只有在try中发生异常,才会进入catch,一旦进入catch,try中剩余代码不会被执行
使用方式:
1.吞没异常,什么都不处理,可以使程序继续运行,搭配throw一起使用
2.只打印异常信息,程序仍可继续运行
3.配合throw或者return使用
4.捕获多个异常按不同需求处理,父异常必须在子异常后面
5.最后要捕获execption或者runtimeexecption
6.一般在catch里面抛出运行时异常
7.catch不抛出异常对象 -> 吞没异常 printStackTrace
throwable的成员方法
1.getMeaasge 显示异常消息
自定义异常步骤:
1.定义异常类
2.写继承关系 大多数继承runtimeeception,也可继承exception
3.生成构造器,一般空参有参都生成
4.按照手动处理异常的方式,声明 抛出 捕获
finally
(1)finally不能单独使用,必须和try…语句或try…catch语句连用
(2)程序运行时,不论是否发生异常,finally代码块都会执行
(3)除非遇到System.exit方法,否则finally代码块一定会执行
9.23 第6天
时间相关类:
1.0 成员方法
Date
SimpleDateFormat 可以对date进行格式化以及解析
TimeZone 时区,根据系统时间来
SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
String str = s.format(date); //格式化
Date parse = s.parse("2023-2-2”);//解析
1.8 静态方法
LocalDateTime 年月日 时分秒 System.out.println(LocalDateTime.now());\
静态方法of自定义时间日期
LocalDate 年月日
LocalTime 时分秒
DateTimeFoamatter
日期格式化 String str = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss));
解析 LocalDate.parse("2022-11-11",DateTimeFormatter.ofPattern("yyyy-MM-dd"))
LocalDate只能解析年月日, LocalDateTime解析年月日时分秒 不能省略
成员方法 加plus 减minus
LocalDateTime l = LocalDateTime.now().minusYears(500);
isAfter() compareTo() isEquals() 比较时间
Instant 时刻类
Instant instant = LocalDateTime.now().toInstant(ZoneOffset.UTC);
//毫秒
instant.toEpochMilli();
//秒
instant.getEpochSecond();
Duration.between(LocalDateTime,LocalDateTime), 对两个时间进行计算
collection
Collection是Java集合框架的根接口,它定义了一些基本的操作和行为,如添加、删除、遍历等。它有两个主要的子接口:List和Set。
List是一个有序的集合,可以包含重复元素。它提供了按索引访问、插入、删除等操作。常见的实现类有ArrayList、LinkedList和Vector。
Set是一个不允许包含重复元素的集合。它提供了高效的元素查找和去重。常见的实现类有HashSet、TreeSet和LinkedHashSet。
ArrayList 增删慢 查找快
add 添加元素
get 获取元素
forEach 循环元素
removeIf 移除元素
sort(Compatator) 指定排序方式
linkedList 增删快查找慢
特有方法
addFirst addLast
getFirst getLast
removeFirst removeLast
9.25 第7天
泛型 Generic
一个类想使用泛型,需要变成泛型类
public class Test<E> {
private E data;
public E getData() {return data;}
public void setData(E data) {this.data = data;}
}
Set 不重复 没有索引概念
TreeSet 除了父类的特点以外,还能够排序
HashSet如果存的是对象,需要重写equals方法
hash :一种算法,根据此算法任意对象都可以输出一个整数值
哈希碰撞:不同的输入得出的哈希值有可能会一样,小概率事件
LinkedHashSet 有序排列
二叉树
红黑树5个平衡约束
1.节点是红色或者黑色
2.红色节点的子节点是黑色
3红色父节点都是黑色
4.不能有两个连续的红色节点
5.任意路径包含相同的黑色节点
枚举 Enum
每一个枚举项其实都是该类的对象
枚举也是一个类,可以定义成员
枚举的第一行必须是枚举项,最后一行最好使用分号
枚举类可以有构造方法,默认private,用法,枚举项(),没有new
枚举类也可以有抽象方法,但是枚举类必须重写该方法, 在枚举项里面重写
注意:
1.枚举要以Enum结尾
2.如果出现固定范围的值, 最好定义两个属性,固定一个区间
3.每一个枚举最好添加一个中文属性
9.26 第8天
HashMap底层数据结构:数组+链表+红黑树
Map<K,V> key是唯一的,k v都可以为null,无序,取不到返回null
顶级父类 Map
常用方法:
put
get
remove
containsKey
containsValue
clear
isEmpty
size
keySet
values
forEach
getOrDefault 不存在就使用默认值
TreeMap 有序排列
LinkHashMap 保证读取顺序
Collections 工具类
Collections.sort 排序
Collections.reverse 翻转
Collections.shuffle 针对list打乱顺序
可变参数 实际上是一个动态数组 如果一个方法包含多个参数,并且有可变参数,可变参数放最后
public void sum(int…a)
不可变集合 jdk9新增 集合接口中的of方法 类名.of()
jdk中有大量不可变集合,unsupportedoperationexception
set调用of不能放相同的元素
HashSet底层用HashMap实现,HashSet的值当成HashMap的键key存储,所以唯一
注解
对程序进行注解和标识
自定义注解:
public @interface 名字{
public 属性类型 属姓名() default 默认值;
}
基本数据类型 String Class 注解 枚举 以上类型的数组
初始化没有给默认值的话,使用的时候需要赋值
四大原注解:
1.Target 指明注解能在哪里使用
2.Retention 生命周期RetentionPolicy.SOURCE 源文件阶段 .CLASS编译阶段 .RUNTIME 运行阶段
3.Inherit
10.5 第9天
单例设计模式 singleton
1.构造器私有化
2.提供静态方法创建对象
3.提供一个静态基本属性
策略模式:Strategy Pattern 案例:switch
在java中,策略模式可以用枚举来实现
Stream
Int[] arr = {1,2,3,3,4};
中间操作
Distinct 去重 Arrays.stream(arr).distinct();
Filter 过滤 Arrays.stream(arr).filter(o->o>3)
Limit 取前几个
Skip 跳过前几个
Map映射(转换)Arrays.stream(arr).map(o->o+3)
String[] name = {“张三”,”李四”};
Arrays.stream(name).map(Teacher::new);
Teacher类中有一个接收string的构造方法
findAny() 查找是否有元素存在
findFirst()
终止操作
foreach
Sum
Max 取最大值 OptionalInt max = Arrays.stream(arr).max()
if(max.isPresent()) sout(max.getAsInt());
Optional 防止为空
orElse 如果不存在,提供默认值
Min
Average
Reduce 归约 折叠,除法不能使用 Arrays.stream(arr).reduce((left,right)->left*right);
终止操作
dis.forEach(System.out::println);
如果区分中间操作和终止操作:看返回值,返回stream就是中间操作
Stream操作不会影响原数据,一旦终止就不能再开启
终止集合操作:collect,要搭配collectors工具类一起使用
toList()
toSet()
toMap(key lambda,value lambda)
toMap(key lambda,value lambda,new value lambda)
toMap(key-key.getBrand,value->value,(a,b) - >b) a是已经存的,b是即将要存的,二选一,也可以重新new一个存
partitioningBygroupingBy数据分区
Concat 拼接流 缺点:每次只能拼接两个流
Stream.concat(steam,steam1).forEach();
flatMap 操作多个stream
Stream<List<Albums>> listStream = artistList.stream().map(a -> a.getAlbumsList());
listStream.flatMap(a -> a.stream()).collect
并行流 parallel 极大的提高cpu核数的利用率,数据顺序不敏感的情况下使用
list.parallelStream 后面的操作跟普通stream一样
10.6 第10天
File file = new File("/Users/a1234/Desktop/test/a");
try {
file.createNewFile();
}catch (Exception e){
e.printStackTrace();
}
createNewFile
getName
Exist
Mkdir
Mkdirs
Delete 只能删除文件跟空文件夹
isDirectory
isFile
List
listFiles
绝对路径 windows :从盘符开始 举例 D:/summer/a.txt
Linux Mac 从根开始,/代表根, 举例 /user/summer/a.txt
相对路径 相对于当前项目下的路径 模块名/具体文件名
Io流体系
字节流:能操作所有类型的文件
流的使用步骤:
1.首先确定流的走向
2.创建流对象
3.调用write read方法
4.关闭流资源 try catch finally———try with resources 1.7 继承了closeable
换行 windows \r\n
Mac \r或者\n
案例1:
FileOutputStream fo = null;
try {
fo = new FileOutputStream("aaa/a.txt"); //覆盖写入
fo = new FileOutputStream("aaa/a.txt",true); //追加写入
String s = "hello world";
fo.write(s.getBytes());
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}catch (IOException e){
e.printStackTrace();
}finally {
if(Objects.nonNull(fo)) {
try {
fo.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
案例2:
try(FileOutputStream fo = new FileOutputStream("aaa/a.txt",true)) {
String s = "\r hello world resources";
fo.write(s.getBytes());
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
文本分类:
1.纯文本,只存字符,txt,java
2.富文本,ppt doc md
把字节数组转换成字符串
byte[] bytes = fi.readAllBytes();
String s = new String (bytes);
读取文件案例:
try (FileInputStream fi = new FileInputStream("aaa/ab.txt");) {
byte[] bytes = new byte[1024];
int length = fi.read(bytes);
String s = "";
while (length >0){
s = new String(bytes, 0,length);
System.out.println(s);
length = fi.read(bytes);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
装饰模式 效率高
BufferedInputStream
BufferedOutputStream
BufferedInputStream bi = new BufferedInputStream(new FileInputStream(sourceString));
BufferedOutputStream bo = new BufferedOutputStream(new FileOutputStream(finalPath));
用法跟 FileInputStream FileOutputStream 一样
装饰模式:灵活增强一个类的功能
10.8 第11天
Java中的编码解码方式:
编码:主要是string类中的getBytes
解码:主要是string类中的构造方法 new String(字节数组)
utf-8:一个中文 3个字节
Unicode:一个中文两个字节
FileReader. BufferedReader 判断是否读完 br.ready()x
FileWriter. BufferedWriter
序列化
实现序列化接口
重写tostring
try (FileOutputStream fo = new FileOutputStream("aaa/a.txt");
ObjectOutputStream oo = new ObjectOutputStream(fo);
){
Student s = new Student(18,"jason");
oo.writeObject(s);
}
反序列化
try (FileInputStream fo = new FileInputStream("aaa/a.txt");
ObjectInputStream oo = new ObjectInputStream(fo);
){
Student s = (Student) oo.readObject();
System.out.println(s);
}
序列化载体:xml Jason protobuf
Properties
最重要的两个方法:store存 load取
10.9 第12天
如何创建线程:
1.继承thread类,重写run方法,创建线程对象,调用start方法启动线程
start跟run的区别:start会启动线程,run只是方法调用
2.实现runnable接口,重写run方法,创建runnable对象,把创建的对象作为参数传递给thread构造器
3 实现callable接口,重写call方法,创建callable对象,创建futuretask对象把callable作为参数传递到构造器中,再把futuretask做的thread的参数传进去,调用start方法,调用get方法获取结果
好处:拿到线程执行结果,方式:搭桥,get
get():阻塞方法
Future 异步 期货
Thread类中的一些方法
静态方法:sleep 休眠
线程是由cpu来调度的,start之后只是进入了就绪状态
线程操作共享数据的安全问题:
解决方案:synchronized关键字同步方法,缺陷:效率低,不够灵活
synchronized: 同步锁,锁的是方法, 首先所有线程参与抢锁
显示锁:ReentrantLock 可重入锁 实现了高并发下的加锁机制,原理是通过AQS(
AbstractQueuedSynchronizer,抽象的队列同步器)中循环调用CAS(compareAndSet,原子性操作)操作来实现加锁,它的性能比较好是因为尽最大努力的避免了使线程进入内核态的阻塞状态
lock.lock();
lock.lock();
try{
// do something
}finally{
lock.unlock();
lock.unlock();
}
同步锁:锁的是方法
互斥锁 :线程互斥,同时只能有一个线程执行加锁的方法
非公平锁:线程抢锁的概率是随机的
隐式锁:看不到锁
可重入锁:同一个线程抢到锁之后可以再次获取该锁
加锁的步骤:
1.首先所有线程参与抢锁
2. 成功抢到锁的线程执行加锁的方法
3.释放锁
死锁:指两个或两个以上的线程在执行过程中,由于竞争资源产生的互相等待资源释放的现象
解決死锁:改变资源的环路等待,顺序获取锁资源
10.11 第13天
线程的状态:跟人一样,人的一生会经过生老病死,线程的一生也会经历各种状态
Java中的线程六种状态
1.新建NEW : 创建了线程对象new Thread
2.运行中RUNNABLE :调用了start方法
3.阳寒BLOCKED :没有获取到锁对象
4.等待WAITING:调用了wait方法
5.计时等待TIME WAITING :调用的sleep
6.结束TERMINATED :线程运行结束.run方法运行完毕
如何使用线程池 默认线程池executors
1.newSingleThreadExecutor 创建单线程池子,即线程池中只有一个线程
2.newCachedThreadPool 创建无限制线程数量的线程池,即任务很多来不及处理时, 会无休止创建线程 线程执行完任务后再归还给线程池
3.newFixedThreadPool
线程池中线程的最大数量由指定参数控制:应用场景:任务不耗时,任务不频繁
4.newScheduledThreadPool 定时任务线程
ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
ses.scheduleAtFixedRate(()-> System.out.println("定时任务"),3,3, TimeUnit.SECONDS);
Executors的弊端
1. newFixedThreadPool和newSingleThreadExecutor • 主要问题是堆积的任务可能会耗费非常大的内存,甚至OOM
2.newCachedThreadPool。 主要问题是线程数最大数是lnteger.MAX VALUE,可能会创建数量非常多的线程,甚至OOM
3.不会拒绝任务
4.跟核酸排队的道理一样,每一个做核酸的人都相当于一个任务.如果排队的人太多,这个时候就应该给出一种拒绝策略,終止排队
手动指定参数线程池ThreadPoolExecutor,七大参数:
1.corePoolSize:核心线程数。是指线程池中长期存活的线程数。
2.maximumPoolSize:最大线程数。最大线程数:线程池允许创建的最大线程数量,当线程池的任务队列满了之后,可以创建的最大线程数。最大线程数 maximumPoolSize 的值不能小于核心线程数 corePoolSize,否则在程序运行时会报 IllegalArgumentException 非法参数异常
3.keepAliveTime:空闲线程存活时间。空闲线程存活时间,当线程池中没有任务时,会销毁一些线程,销毁的线程数=maximumPoolSize(最大线程数)-corePoolSize(核心线程数)。
4.TimeUnit:时间单位。时间单位:空闲线程存活时间的描述单位,此参数是配合参数 3 使用的。
5.BlockingQueue:线程池任务队列。阻塞队列:线程池存放任务的队列,用来存储线程池的所有待执行任务。
6.ThreadFactory:创建线程的工厂。线程工厂:线程池创建线程时调用的工厂方法,通过此方法可以设置线程的优先级、线程命名规则以及线程类型(用户线程还是守护线程)等
7.RejectedExecutionHandler:拒绝策略:当线程池的任务超出线程池队列可以存储的最大值之后,执行的策略。
ThreadPoolExecutor tpe = new ThreadPoolExecutor(1,2,5,
TimeUnit.SECONDS,new ArrayBlockingQueue<>(3),new ThreadPoolExecutor.AbortPolicy());
AtomicInteger index = new AtomicInteger();
for (int i = 0; i < 6; i++) tpe.submit(()-> System.out.println("running " + index.getAndIncrement()));
ArrayBlockingQueue 有界阻塞队列
LinkedBlockingQueue 无界阻塞队列
最大线程数:和数 x 2
任务划分类型:cpu密集型,内存密集型
如何创建线程安全的集合,主要针对集合的增删改查
双列:
ConcurrentHashMap<Object,Object> map = new ConcurrentHashMap<>();
ArrayList<Object> list = new ArrayList<>();
单列:
List safeList = Collections.synchronizedList(list);
CopyOnWriteArrayList
网络通信
计算机通信三要素
1.Ip地址 : 设备在网络中的唯一标识
2.端口 : 应用程序在设备中的唯一标识
3.网络协议 日数据在网络中传输的规则
TCP协议 (Transmission Control Protocol)
UDPt/iX (User Datagram Protocol)
接
public static void main(String[] args) throws IOException {
DatagramSocket datagramSocket = new DatagramSocket(9999);
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length);
while (true){
datagramSocket.receive(datagramPacket);
System.out.println(new String(datagramPacket.getData(),0,datagramPacket.getLength()));
}
}
发
public static void main(String[] args) throws IOException {
DatagramSocket datagramSocket= new DatagramSocket();
byte[] bytes = "hello".getBytes();
DatagramPacket datagramPacket = new DatagramPacket(bytes,bytes.length,InetAddress.getByName("192.168.37.193"),9999);
datagramSocket.send(datagramPacket);
}
10.12 第14天
TCP案例
接收端
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(9999);
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int read;
while ((read = inputStream.read(bytes))!=-1){
String string = new String(bytes,0,read);
System.out.println(string);
}
}
发送端
public static void main(String[] args) {
try(Socket socket = new Socket("192.168.37.199",9999)){
final OutputStream outputStream = socket.getOutputStream();
String s = "饭否";
outputStream.write(s.getBytes());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
日志:解决输出语句的弊端
Simple Logging Facade For Java(Slfj)
日志体系的实现框架1.JUL 2.Log4j 3.LogBack
基于Slf实现的日志框架
logback-core
logback-classic
sifj-api
使用步骤:
1.导入iar包
2.编写logback配置文件
3.代码中获取日志对象
4.设置日志级别
日志6大级别:TRACE< DEBUG< INFO< WARN< ERROR< FATAL
ERROR 用在catch里面
private final static Loggerlogger = LoggerFactory.getLogger(LogTest.class);
public static void main(String[] args) {
System.out.println("输出日志");
logger.info("输出日志");
}
10.15 第15天
获取类对象的三种方式:
Class c1 = Class.forName("day15.classT.Student");
Class c2 = Student.class;
Class c3 = new Student().getClass();
获取构造器:
declared声明的
Constructor[] con1 = c1.getDeclaredConstructors(); //获取全部构造器,包括私有
Constructor[] con2 = c1.getConstructors(); //获取公有构造器
利用构造器创建对象
Constructor constructor = c1.getDeclaredConstructor(String.class,int.class);
constructor.setAccessible(true);
Student jason = (Student)constructor.newInstance("jason", 18);
invoke 调用,唤醒
//获取普通方法
Student student = new Student("Jason",18);
Method study = student.getClass().getDeclaredMethod("study",String.class);
study.setAccessible(true);
study.invoke(student,"Java");
测试工具类,搭配注解使用: @AutoRun 的方法会被调用
Class c1 = Class.forName(classNameString);
Method[] methods = c1.getDeclaredMethods();
for (Method o : methods) {
AutoRun autoRun = o.getDeclaredAnnotation(AutoRun.class);
if (Objects.nonNull(autoRun)){
o.setAccessible(true);
o.invoke(c1.newInstance());
}
}
@AutoRun
public void method1(){
System.out.println("method1 running");
}
反射是框架的灵魂
建造者模式
首先为创建对象使用
1.创建一个静态内部类 Builder
2.原本的类有哪些属性,内部类也得有哪些属性
3.有几个属性,就在内部类中提供几个赋值方法,返回值必须是内部类对象(链式调用:案例:Sting)
4.内部类中提供无参build方法,返回原本类对象
5.新建一个带build的构造器传递参数
10.16 第16天
Mac Maven安装配置
https://www.jianshu.com/p/ded06fd7af86?v=1697418554001
GUI
JPanel
Font font = new Font("微软雅黑",Font.BOLD,30);
g.setColor(Color.RED);
g.setFont(font);
g.drawString("hello",250,250);
g.drawString要在最后调用
组件:
1.组件不能单独显示,必须添加到窗体里才能显示
2.一个容器可以容纳多个组件,调用容器的add方法
3.最常用的两个容器是jframe,jpanel
jpanel默认居中显示,setlayout(null),取消默认布局
网友评论