0%

java学习

java

java构造赋值,先父类后子类,先默认后构造的顺序。

父类与子类:

​ 子父类拥有相同的变量,规则:自己有用自己,自己无用父类。

     父类实现先于子类实现,显式调用父类构造器或者隐藏调用父类无参构造器

​ Serializable接口,相当于一个标志,告诉jvm可以将该类的对象进行序列化和反序列化。(可以使用transient修饰那些不需要序列化的属性),最好自己写一个serialVersionUID(static final long),不会序列化static关键字修饰的属性。如果父类没有实现Serializable接口,那么必须有无参构造函数。

​ Externalizable接口,需要重写writeExternal和readExternal方法,效率比Serializable高,可以决定哪些属性需要序列化(即使transient修饰的),但是面对大量对象,或者重复对象,则效率低。

​ package打包后的类可以不在同一个文件夹中,但是所在文件夹的名字必须与包名一致。

​ import关键字,使用*号时,只会导入该包内的类,并不会导入包。

抽象类:

​ 防止创建没有对象性质的对象(例如:动物),只应该有方法声明,不应该有方法主题。

​ 抽象类也是具有构造函数的,所有子类实现都必须先执行抽象类的构造函数。

​ 抽象类中可以存在0到多个抽象方法,也可存在0到多个非抽象方法

接口:

​ 接口是一种特殊的抽象类,也是引用数据类型(数组,类,接口),包含抽象方法( public abstract),(静态方法和默认方法(default不可省))jdk8以后,成员属性都是常量(public static final)

​ 默认方法,子类不需要重写。

​ 实现接口是为了实现某个功能,是为了进行拓展。

类中代码会在属性初始化之后,无参构造函数之前

static

​ static 关键字修饰的 可以继承 但是不可以重写

final

​ final 修饰成员变量必须赋值(直接赋值,代码块赋值,构造方法赋值),修饰局部变量可以声明和赋值分开。

​ final修饰的形参也是不能改变的

​ final 修饰引用类型,可以更改引用对象。

​ static final 修饰的就是一个常量 (直接赋值,静态代码块赋值)

​ final 修饰的方法不允许被重写

​ final 修饰的类不能被继承

多态

​ 成员属性看左边,成员方法看右边(方法里面用右边变量)

Hashcode编码

​ 用的Object.hash(Object… values) 底层 Arrays.hashCode(values)

实现clone方法

​ 实现Cloneable接口,才能重写Object类的clone方法

javaBean规范

​ 必须要有包

​ 属性私有化

​ get、set方法

​ 实现接口序列化 Serializable

​ public修饰类

​ 增加无参构造函数

String类

​ 底层char数组,String对象永远不变

​ 字符串池的存在,所以字符串字面量是共享的

​ 底层是char数组,所以可以进行char数组和字符串的互转

​ intern方法: (手动优化)如果字符串池中有则返回字符串池中得,否则向池中添加再返回

​ match方法:正则表达式

StringBuilder(异步,不安全)

​ append: 添加

​ insert: 插入位置的前面

​ delete: 删除包前不包后

正则表达式的作用

​ 判断句子是否符合你的规则 match

​ 按照你的规则进行文本切割 split

​ 在文本中替换你想要得格式 replaceAll

. 匹配任意一个字符,除了\n
[] 匹配[]中列举的类型
\d 匹配数字,即0-9
\D 匹配非数字
\s 匹配空白,tab 空格
\S 匹配非空白
\w 匹配单词字符,即a-z,A-Z,_,0-9
\W 匹配非单词字符

正则表达式的斜杠成双原则 \ \ 因为编辑器认为\后的字母应该被转义,但是又找不到应该转义成的字符,我们需要的是一个完整的\d,所以斜杠成双。

* 匹配前一个字符0或无数次,即可有可无
+ 匹配前一个字符1或无数次,即至少有一次
匹配前一个字符1或0次,即不会多于一次
{m} 匹配前一个字符m次
{m,} 匹配前一个字符至少m次
{m,n} 匹配前一个字符m到n次

时间类型

long类型 仅仅是返回值类型 System.currentTimeMillis(), 1970年到现在的毫秒数

Data类型 日期 桥梁 由于千年虫事件 基本上不使用 被用来进行long类型和Calendar类型的数据转换以及时间的展示

Calendar类型 日历 日期的运算 属于抽象类,使用它的子类(GregorianGalendar)进行实例化,或者使用Calendar中的getInstance()方法 子类gregorianCalendar

从字符串转换为时间类型 DateFormat 抽象类,子类simpleDateFormat

格式化 date–》string

解析 string—》date

集合类型

​ Collection 接口

add,remove,size,contains

addAll, 合并不会去重

removeAll, 去重交集

retainAll 得到交集

根据类型的equals和hashcode进行判断

List接口 ===默认为集合 (有序、重复)

List允许出现重复元素,线性方式的有序存储,通过索引来访问集合中的指定元素

*如果list是Integer泛型的话,如果使用remove方法,这里必须要理解的是:如果不需要自动装箱就能调用方法的话,就不会进行自动装箱。

ArrayList在操作指定下标的任意元素上面,速度比较快。(查找上和指定下标操作的操作上速度比较快)。

LinkedList底层是双向链表,所以在操作首尾元素的操作上速度比较快。

vector自从ArrayList出现以后,就不再使用了

迭代器

相当于把所有的集合元素按照他们指定的顺序排放在一个类似于线性表的集合中。

使用集合对象调用iterator方法,获取iterator对象,如果有泛型,iterator也可以使用相应的泛型。

泛型

为了将运行时异常转换为编译时异常(深层次)

泛型不存在继承关系

set接口

set接口中的元素无序,并且存入的元素不重复出现。

HashSet

​ 无序且不重复、重写hashcode和equals方法

LinkedHashSet

​ 有序

TreeSet(实现了set和sortset)

​ 具有自然排序功能的类

​ 可以自定义排序

​ 不重复,不能放null

​ 因为TreeSet这个类需要吧里面的元素进行统一类型来比较,所以会配套使用泛型

​ TreeSet对自定义数据类型进行排序的话,需要两个前提

​ 实现comparable接口

​ 有具体的排序方法

比较器

在java中有两个常用的接口,分别是Comparator接口和Comparable接口

Comparator接口

​ 临时 重写 compare方法 两个参数

​ 经常在Arrays.sort以及Collections.sort里面来使用

​ 不能在TreeSet中使用

​ 使用内名内部类

Comparable接口

​ 持久 重写 compareTo方法 一个参数

1
2
3
// 都返回0的话,就会输出一个元素
// 返回正数时,代表该属性值的升序-->本身属性-参数属性
// 返回负数时,代表该属性值的降序-->参数属性-本身属性

Map接口

等同于set的定义,建唯一不重复。键值对

​ 键 无序、无下标、不允许重复

​ 值 无序、无下标、允许重复

HashMap 不能保证顺序,键采用自定义类型时,就要重写hashCode和equals方法

LinkedHashMap 多了排序的功能

TreeSet 自然排序且键不重复,可以采用自定义比较。

HashMap与Hashtable的关系 ArrayList和vector的关系

Throwable

​ 编写错误不属于异常(需要try catch的才是编译型异常)

​ printStackTrace() 打印异常的详细信息。包含了异常的类型,异常的原因,异常出现的位置

​ getMessage() 获取异常的原因

​ toString() 获取异常的类型和异常描述信息

异常处理方式

​ try catch finally 不加catch的话会结束程序的执行

​ throw 后面跟异常对象 并且结束当前方法的执行

​ throw 后面如果接运行时环境,一旦改代码执行,那么程序会停止,如果后面是检查时异常,就会要求你处理异常,程序不会停止。

​ 如果throw后面跟的是一个编译时异常,jvm就会要求你必须处理此异常

​ throws 放在方法结构尾部,用来告诉方法的调用者,这个方法有异常。

​ Exception 和 继承Exception类的子类 属于编译期异常(除了RuntimeException 和 它的子类)

​ RuntimeException和继承 了RuntimeException的子类

​ 自定义异常就是继承Exception或RuntimeException

反射

​ 通过字节码对象获取,把类的各个组成部分(属性,构造函数和方法)给获取到

​ 能干什么?

​ 获取类的相关信息,动态调用方法,动态调用属性

Class类

1
2
3
4
5
6
7
8
9

getName forName newInstance

getField(String) getDeclaredField(String) getFields getDeclaredFields

getMethod(String name,Class... <?> parameterType) getDeclaredField getMethods getDeclaredFields

getConstructor(Class... <?> parameterType) getDeclaredField getConstructors getDeclaredFields

Field类

1
2
3
4
get(Object o); // 返回一个Object 获取该对象的相对应的属性
set(Object o, 值) // 修改该对象的值
// NoSuchFieldException 获取非公有属性 解决 getDeclaredField
// IllegalAccessException 非法访问 解决 使用之前赋予权限 setAccessible(true)

Method类

1
2
3
4
get(Object,Class...<?> ParameterType ) // ParameterType 是类型,不是具体的值
invoke(Object o , Object... Parameter) // Parameter为具体的值
// NoSuchFieldException 获取非公有属性 解决 getDeclaredMethod
// IllegalAccessException 非法访问 解决 使用之前赋予权限 setAccessible(true)

Constructor类

1
2
newInstance // 创建一个新对象

工厂设计模式

这个创建模式让我们在创建对象时不会暴露创建逻辑,而是通过使用一个共同的接口来完成对象的创建

简单工厂、工厂方法、抽象工厂

优点:

​ 调用者想创建一个对象,只需要知道其名称,

​ 拓展性强,想增加产品,只要扩展产品类

​ 屏蔽产品的具体实现,无需关心内部实现

​ 面向接口编程

IO流

File类 (不能读/写文件内容,只能操作文件或文件夹的属性)文件或目录路径的抽象表现形式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
exist() // 是否存在
createNewFile() // 创建新文件 eg\创建文件的目录必须存在
isHidden()// 判断文件是否隐藏
isFile()// 判断是否为普通的文件
length() // 文件的长度
isDirectory()//是否为文件夹
mkdir()//创建一个文件夹
mkdirs()//创建层级文件夹
renameTo(File dest) // 更改文件的名字
delete() // 删除文件 eg、如果删除文件夹,文件夹下面不能有文件
listFiles() // 列出指定路径下的所有文件
getAbsolutePath() //获取绝对路径
getCanonicalPath() // 获取规范形式 建议使用
getName() // 只有文件名
getPath() // 路径名字
listFile(FileFilter filter)

流对象

字节流

1
2
3
4
5
6
7
8
9
InputStream  实现了Closeable接口,可以被关闭
FileInputStream
FilterInputStream // 相当于私人订制
BufferedInputStream
DataInputStream // 专门处理基本数据类型的流
PushbakInputStream
ObjectInputStream
OutputStream 实现了closeable,Flushable接口

InputStream

  • available() 返回长度

FileOutputStream

  • read() 已经读完的情况下在读是-1 返回的是游标的位置

字符流

1
2
3
4
5
6
7
8
Reader
BufferedReader 常用
InputStreamReader
FileReader
Writer
BufferedWriter 常用
OutputStreamWriter
FileWriter

BufferedReader

  • Read 文件末尾返回null

BufferedWriter

  • write
  • append
  • newline 另起一行

PrinterWriter

  • PrinterWriter(String str)

序列化和反序列化

ObjectOutputStream和ObjectInputStream

一个类要实现序列化,它本身和它的属性必须都实现序列化。对父类无要求

serialVersionUID 使用来标识类的,来判断是否是同一个类,不写的话会自动计算生成

不想属性进行序列化解决方法

  • 加上static(类资源不会进行序列化)
  • 加上transient修饰词(当类实现的是Externalizable接口时,可以通过重写序列化和反序列化的方法指定某些属性进行序列化和反序列化,这时transient关键字失效)

线程

一个线程可以创建和撤销另一个线程

线程基本上不拥有系统资源

线程之间交替工作,被称为多线程。

线程的组成

  • cpu时间片
  • 运行数据(栈内存、堆内存)
  • 线程的业务逻辑代码

同步(并发)多个线程按照一定的顺序逐个进行执行。

异步(并行)多个线程一起不按顺序的执行。

1、多线程的创建

Thread类 实现run方法,调用start方法(如果执行run方法,不会开启一个新的线程)

  • 多个线程分别完成自己的任务

Runnable接口 实现run方法,但是还需要Threand类的start方法

  • 多个线程共同完成一个任务
  • 线程池只能放入实现Runable或Callable类线程,不能放入Thread子类

指定多线程的名字 setName方法

多线程的状态管理(生命周期)

New状态:多线程被创建出来,还没有调用start方法之前,属于这种状态。

Ready状态:调用了start方法,此时处于多个线程在争夺cpu使用权。

Runnable状态:当某个多线程抢夺到了cpu的使用权,并且开始运行他的业务逻辑的时候

Block状态:当多线程由于外部原因导致它无法继续执行业务逻辑的时候,

  • a、锁阻塞
  • b、指定时长的等待
  • c、不指定时长的等待

Terminated状态:当多线程业务逻辑执行完毕,属于这种状态,一旦进入这种状态,线程对象就无法调用方法了。

线程的常用方法

  • 静态方法

    • currentThread() 获取当前的线程对象
    • sleep() 让当前线程休眠(注意 因为是静态方法,所以不是按对象执行,而是看当前执行方法的线程) 如 在 t1 t2 线程,在t2中调用t1.sleep() ,t2休眠而不是t1休眠。
    • activeCount() 获取当前线程组的活动线程数量。
    • yield() 暂停当前线程的运行,让其进入就绪状态和其他的就绪线程抢夺资源。
  • 线程相关信息的方法

    • getName()/setName() 线程的名字
    • getId 线程的id标识符
    • getPriority()/setPriority() 线程的优先级
    • getState()线程的状态
    • setDaemon(boolean on) 标记为守护线程或用户线程
  • 守护线程

    • 守护线程,我们也称为后台线程或者是用户线程。
    • 一旦你设置了某个线程为守护线程的话,那么该线程会等待其他线程都结束,它就会自动结束,所以是守护线程我们一般不会设置其有效时间,会让它一直有效,典型的守护线程就是垃圾回收线程
    • 设置一个线程为守护线程要在start方法调用之前来设置。
  • 线程判断的方法

    • isAlive()
    • isDaemon()
    • isInterupted()
  • 其他

    • join()等待该线程终止再开始其他线程 放在start之后调用才有效

线程安全

多个线程同时使用同一个共享资源所导致的。

解决方法 锁(synchronized)

  • 对资源进行加锁

互斥锁的使用方式

  • 隐式锁
    • 代码块上锁
    • 方法上锁
  • 显式锁
    • lock上锁(jdk1.5之后)

代码块加锁

​ synchronized关键字可以用于方法的某个区域中,

​ synchronized(同步锁){

​ 需要同步操作的代码

​ }

​ 同步锁的解释

​ 对象的同步锁只是一个概念,可以想象为在对象上标记了一个锁,同步锁的要求:

​ 1、所对象可以是任意类型,我们一般直接使用Object对象

​ 2、保证这些线程对象使用的是同一把锁。

​ 注意:

​ 1、在任意时候,最多允许一个线程拥有同步锁,谁拿到锁就进入代码,其余代码只能在外边等着(Blocked)

​ 2、对于非static方法,同步锁就是this。对于static方法,我们使用当前方法所在类的字节码对象。

​ ps:sleep不释放锁资源,wait释放锁资源。

​ 可以使用lock接口,ReentrantLock是lock的实现类

​ 方法

​ lock()

​ unlock()

多线程唤醒的三种方式

​ interrupt() sleep()

​ notify()

​ notifyAll()

线程通信

​ 让多个线程之间可以进行进行同一件事情,需要线程之间进行协调。

​ wait和notify函数必须在同步代码块后者同步函数中使用。

线程池

使用:

​ 1、使用线程池的工具类Executors里面所提供的静态方法newFixedThreadPool(int nThreads)来构建一个指定线程数量的线程池对象。

​ 2、创建一个Runnable的子类,然后在run方法中写明你的任务逻辑代码。

​ 3、通过创建出来的ExecutorServices对象中的submit方法来执行你创建的Runnable子类。

​ 4、如果你不再使用线程池了,可以用shutDown()关闭它。

新特性

​ 1、lambda表达式

​ 2、方法引用

​ 有现成的方法使用,就是用现成的方法。(相当于对lambda表达式的进一步优化)

​ testInterface2(System.out::println)

​ 3、函数式接口

​ 就是符合lambda表达式的接口,确保接口中有且只有一个抽象方法

​ 在接口上使用@FunctionalInterface注解,如果是函数式接口,则编译通过,否则不通过。

​ 可以作为参数和返回类型。

​ 四种新常用的函数式接口(1.8)

​ Supplier接口 提供一个数据

1
2
3
4
Supplier<T>:包含一个无参的方法,用来获取一个泛型参数指定类型的对象数据。
Tget():获得结果,不需要参数,它会按照某种实现逻辑(由 Lambda表达式实现返回一个数据
Supplier<T>接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会
生产什么类型的数据供我们使用

​ Consumer接口

1
2
3
4
Consumer<T>:也被称为消费型接口,该接口正好与 Supplier接口相反,它不是生产一个数据,而是消费一
个数据,其数据类型由泛型决定。
void accept(T t):对给定的参数执行此操作。
default Consumer<T> andthen( Consumer after):返回一个组合的 Consumer,依次执行此操作,然后执行 afterf操作。

​ Predicate接口

1
2
3
4
5
Predicate<T>:通常用于判断参数是否满足指定的条件
boolean test(Tt):对给定的参数进行判断(判断逻辑由 Lambda表达式实现),返回一个布尔值
default Predicates> negate():返回一个逻辑的否定,对应逻辑非
default Predicate<T>and( Predicate other):返回一个组合判断,对应短路与
default Predicate<T>or( Predicate other):返回一个组合判断,对应短路或

​ Function接口

1
2
3
4
Function<T,R>:接口通常用于对参数进行处理,转換(处理逻辑由 Lambda表达式实现),然后返回一个新的值
Apply(Tt):将此函数应用于给定的参数
default<V> Function andthen( Function after):返回一个组合函数,首先将该函数应用于输入,然后将 after
函数应用于结果

stream流

流可以理解为是一种用来处理数据容器的东西。可以和lambda表达式相结合一起进行操作。

流的生成

​ 1、Collection接口下的子类

​ list.stream() set.stream()

​ 2、Map接口下的子类

​ 根据需求来进行键、值或者Entry对象的转换为stream流

​ map.keySet().stream() map.values().stream() map.entrySet().stream()

​ 3、数组

​ 直接调用Stream类的静态方法of

​ Stream.of(strArray)

​ 4、结束流

​ count forEach

​ 5、Stream转换到Collection

​ R collect(Collector collector)

​ Collectors工具类

​ public static Collector toList() : 把元素收集到list集合中

​ public static Collector toSet() : 把元素收集到set集合中

​ public static Collector toMap(Function keyMapper,Function valueMapper) : 把元素收集到map集合中


东软

操作数栈的概念

jdbc的连接步骤(引入jar包,mysql connector/J , lombok @Data, )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1、选择数据库的种类  Class.forName("com.mysql.jdbc.Driver")
2、创建连接,数据库地址,用户名、地址 Connnetion conn = DriverManager.getConnnection("jdbc:mysql://192.168.80.131:3306/db1?useUnicode=true&characterEncoding=utf8","root","123456");
3、选择要操作的数据库
上一步已经写好了
4、写sql语句
con.createStatement(String sql) // 少数 无预编译
PrepareStatement pstmt = con.prepareStataement(String sql) // 多数 有预编译
5、执行sql语句
ResultSet rs = pstmt.executeQuery();
6、处理结果集
while(rs.next()){

}

泛型逆向推到必须要写

单继承多实现

抽象类中可以有构造方法,接口中不可以有构造方法。

抽象类中可以有抽象方法和非抽象方法,接口中可以有非抽象方法(jdk8及以后)

字符流字节流之间转换: inputStreamReader bufferedReader

远程调用 一个机器上的controller层调用另一台机器上的service层 通过url调用

跨语言无法传输字节流,可以使用json或xml格式

分布式:将程序分为一个个的模块项目。(简单来说就是合力做一件事)

消息中间件:类似于数组。英文全称“Message Queue”,简称MQ。

事务:事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤 消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。

事务的四大特性:ACID,原子性(Atomicity),一致性(correspondence),隔离性(Isolation),持久性(durability)。

​ (1)原子性:整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
​ (2)一致性:在事务开始之前和事务结束以后,数据库的完整性约束没有被破坏。
​ (3)隔离性:隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行 相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。这种属性有时称为串行化,为了防止事务操作间的混淆, 必须串行化或序列化请 求,使得在同一时间仅有一个请求用于同一数据。
​ (4)持久性:在事务完成以后,该事务所对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

进程:正在运行的程序

线程:是操作系统能够进行运算调度的最小单位,是进程中的实际运作单位。

javaee是通讯框架

单例模式

私有化构造方法

​ 饥饿式:先构造一个static的对象

​ 懒汉式: 先设置一个为null的static的变量,等调用对象的时候再进行生成。 因为是单实例多线程的调用需要加锁。