Java SE

Java知识总结

1.Java基本常识

Java三大版本

Java SE 标准版,桌面程序,控制台开发等

Java ME 嵌入式开发(凉了)

Java EE E企业级开发(偏向服务器开发,web端)

JDK、JRE、JVM

JDK,Java工具包

JRE,Java运行时环境

JVM,Java虚拟机

编译器和解释器

编译器是把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以机器语言来运行此程序,速度很快;
解释器则是只在执行程序时,才一条一条的解释成机器语言给计算机来执行,所以运行速度是不如编译后的程序运行的快的。

Java语言先编译,后解释

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u7G4dj0M-1606650294383)(F:\blog\hexo\source\assets\image-20200912125949889.png)]

Array类(关于数组的工具类),fill函数(初始化函数;print

2.面向对象

面向对象编程的本质就是:以类的方式组织代码,以对象的组织封装数据

Java三大特性

封装

封装属性,不提供直接访问的实际数据,只提供接口进行访问,即属性私有

继承

Java类中只有单继承,没有多继承(即只有一个父类)

子类可以使用父类除私有之外的属性或方法

可送给super关键字访问父类的属性或者方法

super只能出现在子类的方法或者构造方法中,super和this不能同时调用构造方法

this(本类) 和 super(父类)

重写

必须是子类重写父类的非静态方法,方法名必须相同,参数必须相同

修饰符可以扩大但不能缩小 例如protected可以扩大为public,但是public不能缩小为protected。

重写都是方法的重写,和属性无关

父类的引用指向了子类

多态

多态是方法的多态,属性没有多态

存在条件:继承,方法重写、向上转型

向上转型、向下转型

向上转型:父类引用指向子类对象。

向下转型:子类引用指向父类对象,前提是父类对象指向子类对象(也即向上转型)。

Father f1 = new Son();   // 这就叫 upcasting (向上转型)
// 现在 f1 引用指向一个Son对象

Son s1 = (Son)f1;   // 这就叫 downcasting (向下转型)
// 现在f1 还是指向 Son对象
final 被final修饰的是常量,不能被重写
instancof 判断子类和父类是否有继承关系

抽象类(abstract关键字定义)

抽象类,包含抽象方法,只定义不实现,由子类实现。抽象类不能new出来。

抽象类可以包含正常的方法,但是抽象方法必须在抽象类中

抽象类包含构造方法

接口(interface关键字定义)

接口只包含抽象方法

接口只包含常量的属性,即(static final)

接口可以多继承,接口的所有方法都要由子类实现

类可以通过implements实现接口,而且必须实现接口的所有方法

接口不包含构造方法

相同点

接口和抽象类都不能实例化
都位于继承的顶端,用于被其他实现或继承
都包含抽象方法,其子类都必须覆写这些抽象方法

抽象类能使用 final 修饰吗?

不能,定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能修饰抽象类

内部类

内部类可以访问外部类的私有变量、方法。

定义在类内部的静态类,就是静态内部类

定义在类内部,成员位置上的非静态类,就是成员内部类

定义在方法中的内部类,就是局部内部类

匿名内部类就是没有名字的内部类,日常开发中使用的比较多。

静态内部类:静态内部类可以访问外部类所有的静态变量,而不可访问外部类的非静态变量;静态内部类的创建方式,new 外部类.静态内部类()

成员内部类:成员内部类可以访问外部类所有的变量和方法,包括静态和非静态,私有和公有。成员内部类依赖于外部类的实例,它的创建方式外部类实例.new 内部类()。

局部内部类:定义在实例方法中的局部类可以访问外部类的所有变量和方法,定义在静态方法中的局部类只能访问外部类的静态变量和方法。局部内部类的创建方式,在对应方法内,new 内部类()

匿名内部类:除了没有名字,匿名内部类还有以下特点:

匿名内部类必须继承一个抽象类或者实现一个接口。
匿名内部类不能定义任何静态成员和静态方法。
当所在的方法的形参需要被匿名内部类使用时,必须声明为 final。
匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。

反射

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

优点: 运行期类型的判断,动态加载类,提高代码灵活度。
缺点: 性能瓶颈:反射相当于一系列解释操作,通知 JVM 要做的事情,性能比直接的java代码要慢很多。

应用:

反射是框架设计的灵魂。

jdbc的class.forname()、spring框架都用了反射机制。

Java获取反射的三种方法
1.通过new对象实现反射机制

2.通过路径实现反射机制

3.通过类名实现反射机制

装箱、拆箱

Integer a= 127 与 Integer b = 127相等吗
对于对象引用类型:==比较的是对象的内存地址。
对于基本数据类型:==比较的是值。

如果整型字面量的值在-128到127之间,那么自动装箱时不会new新的Integer对象,而是直接引用常量池中的Integer对象,超过范围 a1==b1的结果是false

异常

try和catch关键字连用,也可使用finally

throw用于主动抛出异常,th rows用于方法上抛出异常

3.Java多线程

  • 线程就是独立的执行路径
  • 即使进程没有创建线程,也会有多个线程,例如主线程,GC线程(垃圾回收)
  • main()为主线程,为系统的入口,执行整个程序
  • 在一个进程中,如果开辟了多个线程,线程的运行由调度器安排。
  • 线程对同一资源访问时,会存在资源抢夺的问题,需要加入并发控制
  • 线程会带来额外开销,例如CPU调度开销,并发控制开销
  • 每个线程在自己的工作内存交互,内存控制不当会导致数据不一致

进程与线程的区别

根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位

资源开销:每个进程有独立的代码和数据空间,程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。

包含关系:一个进程可以包含多个线程。

内存分配:同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的。

1)多线程创建与使用

可通过继承Thread类或者重写runnable接口实现,run方法写要创建多线程的代码,start()方法启动。

继承Thread类的多线程创建:

Thread1 thread1 = new Thread1();
thread1.start();

重写runnablde

Thread3 thread3 = new Thread3();
new Thread(thread3).start();

由于单继承局限性,推荐重写runnable创建多线程

也可通过扩展callable接口(重写call方法,有返回值)

//创建线程
Callable1 t1 = new Callable1();
//创建执行服务
ExecutorService ser = Executors.newFixedThreadPool(3);//多线程池
//提交执行
Future<Boolean> r1 = ser.submit(t1);
//获取结果
boolean rs1 = r1.get();//需要抛出异常
//关闭服务
ser.shutdown();

线程池:executorService,线程池接口;executors,线程池工厂,用于创建并返回不同类型的线程池。

1、创建服务
ExecutorService service = Executors.newFixedThreadPool(10);创建十个线程的线程池
service.execute(Thread);//执行服务
service.shutdown;//关闭服务
FutureTask

FutureTask 表示一个异步运算的任务。FutureTask 里面可以传入一个 Callable 的具体实现类,可以对这个异步运算的任务的结果进行等待获取、判断是否已经完成、取消任务等操作。只有当运算完成的时候结果才能取回,如果运算尚未完成 get 方法将会阻塞。一个 FutureTask 对象可以对调用了 Callable 和 Runnable 的对象进行包装,由于 FutureTask 也是Runnable 接口的实现类,所以 FutureTask 也可以放入线程池中。

FutureTask实现了RunnableFuture接口,同时具有Runnable、Future的能力,即既可以作为Future得到Callable的返回值,又可以作为一个Runnable。

img

2)并发问题

资源争抢导致的数据不一致问题

线程类的构造方法、静态块是被哪个线程调用的

这是一个非常刁钻和狡猾的问题。请记住:线程类的构造方法、静态块是被 new这个线程类所在的线程所调用的,而 run 方法里面的代码才是被线程自身所调用的。

3)静态代理

婚庆公司帮助people完成结婚工作
WeddingCompany weddingCompany = new WeddingCompany(new People());//创建代理对象和目标对象
weddingCompany.marry("小明");//让代理对象完成目标对象的工作
1、分为真实对象和代理对象;
2、真实对象和代理对象都要实现同一个接口
3、代理对象要代理真实角色
4、代理对象的作用是 实现一些真实对象没有实现的功能(真实对象专注做自己的功能,无需关心其它

4)lambda表达式

new Thread(() -> System.out.println("实现runnab接口的函数体")).start();//lambda表达式
()表示参数
 箭头后面的是函数体
    即
    () -> {
    System.out.println("实现runnab接口的函数体");
}
只有一行也可去掉花括号
函数式接口

任何接口,如果只包含一个抽象方法,那就是函数式接口。对于函数式接口,就可以通过lambda表达式来创建该接口的对象

5)线程

线程状态

创建状态、就绪状态、运行状态、阻塞状态、死亡状态

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nl4GkCNG-1606650294385)(F:\blog\hexo\source\assets\image-20200922202326646.png)]

线程方法
停止线程

jdk的方法如stop、destroy已经过时不推荐使用,建议使用标志位,打到某个条件后让线程自己停下来

如果想要线程强制停止,推荐使用外部标志位写一个stop方法强制停止

推荐让线程自然停止

线程休眠

sleep(时间)指定当前线程的阻塞毫秒数

sleep存在异常InterruptedException

sleep时间到达后线程进行就绪状态

sleep可以模拟网络延时,计时等

sleep不会释放锁

线程礼让

礼让线程,让当前正在执行的线程暂停,但不阻塞

让线程从运行状态变成就绪状态

让cpu重新调度

join(线程插队)

join强制执行当前线程,待此线程执行完毕后,再执行其他线程,其他线程堵塞

尽量少使用,会让线程堵塞

线程观测状态
Thread.State state = thread.getState();
System.out.println(state);

有 new状态、runnable(运行)状态、BLOCKED状态、TERMINATED(死亡)状态TIMED_WAITING(就绪状态)

线程的优先级
Thread t1 = new Thread(new MyPriority(),"t1");
t1.start();
t2.setPriority(5);

通过设置线程优先级来使线程先运行或者后运行,优先级高的先运行,低的后运行

默认优先级是5,范围是1-10,超过范围会报错

守护(daemon)线程

线程分为用户线程和守护线程

虚拟机必须确保用户线程执行完毕

虚拟机不必等待守护线程执行完毕

守护线程如GC(垃圾回收线程),后台记录日志,垃圾回收等

线程同步

synchronize

线程不同步导致数据安全问题

保证线程安全:队列+锁,在访问数据时,加入锁机制synchronize(会影响效率)

同步块 synchronized(obj){}
obj称为同步监视器
obj可以是任何对象,但是推荐使用共享资源作为同步监视器
同步方法中无需指定同步监视器,因为同步方法的同步监视器就是this,就是这个对象本身,或者是class(反射)
同步监视器执行过程
1、第一个线程访问,锁定同步监视器,执行其中代码
2、第二个线程访问,发现同步监视器被锁定,无法访问
3、第一个线程访问完毕,锁解开,第二个线程访问

ArrayList是线程不安全的

copyonwriteArrayList是线程安全的

死锁

多个线程互相抱着对方所需的资源,然后形成僵持,谁也执行不了

死锁的四个形成必要条件:

1、资源互斥,所访问的资源的互斥的,不能同时访问

2、请求与保持,一个线程请求资源时,对所拥有的资源保持不放

3、不可抢占,所拥有的资源不能被其它线程抢占

4、循环等待,若干线程形成互相等待的关系。

lock锁
private final ReentrantLck lock = new ReenTrantLock();
	lock.lock()
    try{
        
    }finally{
        lock.unlock()
    }

线程协作,生产者消费者模式

生产者和消费者共享同一个资源,并且生产者和消费者之间相互依赖,形成条件

生产者 - 数据缓冲区- 消费者

线程通信

wait()线程进入堵塞状态

notify()唤醒一个处于wait状态的线程

notifyall()唤醒所有

并发协作模型 管程法/信号灯法

管程法:利用一个数据缓冲区存储生产者消费的商品,生产者生产商品直到缓冲区满,消费者消费商品直到没有。

信号灯法:设立标志位标志是否有产品。

4.Java IO流

什么是流? 就是进程在内存与存储设备中交换数据的通道。

Java Io流共涉及40多个类,这些类看上去很杂乱,但实际上很有规则,而且彼此之间存在非常紧密的联系, Java I0流的40多个类都是从如下4个抽象类基类中派生出来的。

InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流。
OutputStream/Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。

流的分类:

按流向分:输入流、输出流

按传输单位分:字节流(可读取所有数据)、字符流(可读取文本数据)

按功能分:节点流(具有数据传输数据的功能)、过滤流(在节点流的基础上增强功能)

img

字节流

InputStream、OutputStream
FileInputStream、FileOutputStream
字节输入流
file.open();
file.read();
file.close();
字节输出流
FileOutputStream outp = new FileOutputStream("C:\\Users\\123456\\Desktop\\Java知识总结\\test.txt");
        outp.write(97);
        outp.write('a');
        outp.write(bytes);
        outp.close();
缓冲流 需要先给予filestream,即过滤流需要传递节点流
BufferedInputStream 
BufferedOutputStream
序列化和反序列化 需要先给予filestream
ObjectOutputStream//序列化对象,将对象转化为字节流
被序列化的对象需要实现接口Serializable(仅仅是标志接口,标志该对象可以被序列化)

ObjectInputStream//反序列化

序列化和反序列化

注意事项:

1、被序列化的对象需要实现接口Serializable(仅仅是标志接口,标志该对象可以被序列化)

2、被序列化的对象的对象属性也要实现serializable接口

3、序列化版本ID,确保序列化的类和反序列化的类是同一个类

版本号ID serialVerID = 100L;

4、使用transien修饰的属性,不能被序列化,也就是序列化该对象该属性会消失

5、静态属性不能被序列化

字符流

父类:Reader、Writer

缓冲流 需要先给予filestream,即过滤流需要传递节点流
BufferedInputStream
BufferedOutputStream
序列化和反序列化 需要先给予filestream
ObjectOutputStream//序列化对象,将对象转化为字节流
被序列化的对象需要实现接口Serializable(仅仅是标志接口,标志该对象可以被序列化)

ObjectInputStream//反序列化


#### 序列化和反序列化

注意事项:

1、被序列化的对象需要实现接口Serializable(仅仅是标志接口,标志该对象可以被序列化)

2、被序列化的对象的对象属性也要实现serializable接口

3、序列化版本ID,确保序列化的类和反序列化的类是同一个类

版本号ID serialVerID = 100L;


4、使用transien修饰的属性,不能被序列化,也就是序列化该对象该属性会消失

5、静态属性不能被序列化

### 字符流

父类:Reader、Writer

子类:filereade、filewriter
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值