美文网首页
Java基础笔记

Java基础笔记

作者: yuaixing003 | 来源:发表于2023-10-14 17:49 被阅读0次

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),取消默认布局

相关文章

网友评论

      本文标题:Java基础笔记

      本文链接:https://www.haomeiwen.com/subject/trszbdtx.html