Java基础-JDK各版本特性汇总(JDK1.0~JDK18)
参考文献
JRE Version
123456789101112131415161749 = Java 550 = Java 651 = Java 752 = Java 853 = Java 954 = Java 1055 = Java 1156 = Java 1257 = Java 1358 = Java 1459 = Java 1560 = Java 1661 = Java 1762 = Java 1863 = Java 1964 = Java 2065 = Java 21
JDK各版本特性汇总(JDK1.0~JDK18)
JDK版本
发布时间
代号
备注
1
1996年1月23日
Oak(橡树)
初代版本,伟大的一个里程碑,但是是纯解释运行,使用JIT,性能比较差,速度慢
1.1
1997年2月19日
Sparkler(宝石)
JDBC、支持内部类、RMI、反射等等
1.2
1998年12月8日
Playground(操场)
集合框架、JIT等等
1.3
2000年5月8日
Kestrel(红隼)
对Java的各个方面都做了大量优化和增强
1.4
2 ...
JavaNIO-Socket
参考文献
非阻塞 vs 阻塞
阻塞
阻塞模式下,相关方法都会导致线程暂停
ServerSocketChannel.accept 会在没有连接建立时让线程暂停
SocketChannel.read 会在没有数据可读时让线程暂停
阻塞的表现其实就是线程暂停了,暂停期间不会占用 cpu,但线程相当于闲置
单线程下,阻塞方法之间相互影响,几乎不能正常工作,需要多线程支持
但多线程下,有新的问题,体现在以下方面
32 位 jvm一个线程 320k,64 位 jvm 一个线程1024k,如果连接数过多,必然导致 OOM,并且线程太多,反而会因为频繁上下文切换导致性能降低
可以采用线程池技术来减少线程数和线程上下文切换,但治标不治本,如果有很多连接建立,但长时间inactive,会阻塞线程池中所有线程,因此不适合长连接,只适合短连接.
服务器端
123456789101112131415161718192021222324252627// 使用 nio 来理解阻塞模式, 单线程// 0. ByteBufferByteBuffer buffer = ByteBuffer.allocat ...
Java基础-SPI机制
参考文献
Java SPI 机制详解
SPI机制
JDK SPI(Service Provider Interface)机制是一种基于接口的服务发现机制,它允许应用程序在运行时动态地查找和加载实现某个接口的服务提供者.
在每次类加载的时候会先去找到 class 相对目录下的 META-INF 文件夹下的 services 文件夹下的文件,将这个文件夹下面的所有文件先加载到内存中,然后根据这些文件的文件名和里面的文件内容找到相应接口的具体实现类,找到实现类后就可以通过反射去生成对应的对象,保存在一个 list 列表里面,所以可以通过迭代或者遍历的方式拿到对应的实例对象,生成不同的实现.
JDK SPI 机制的基本原理如下:
定义接口: 定义一个接口,其实现类将作为服务提供者.
配置文件: 在 META-INF/services目录下创建一个以接口全限定名命名的文本文件,该文件的内容是实现该接口的服务提供者的全限定名.
文件名一定要是接口的全类名,然后里面的内容一定要是实现类的全类名,实现类可以有多个,直接换行就好了,多个实现类的时候,会一个一个的迭代加载.
服务加 ...
Java基础-数据库配置
参考文献
JDBC连接数据库的流程
在开发环境中加载指定数据库的驱动程序
在Java程序中加载程序
1ClassName.forName("com.mysql.cj.jdbc.Driver");
创建数据连接对象
12// URL = 协议名 + IP地址 + 端口 + 数据库名称Connection connection = DriverManager.getConnection("连接数据库的URL","用户名","密码");
创建Statement对象
1Statement statement = connection.createStatement();
调用Statement对象的相关方法执行对应的SQL
1ResultSet resulte = statement.excuteUpdate("SQL");
关闭数据库连接
1connection.close();
各种数据库URL配置
1234567891011121314mysql:jdbc:my ...
Java基础-网络
参考文献
Java语言程序设计-进阶版(第8版)
Java核心技术 卷2 高级特性
引言
Java支持基于流的通信(stream-based communication)和基于包通信(packet-based communication).
基于流的通信使用传输控制协议TCP进行数据传输,而基于包的通信使用用户数据协议UDP.
Java API提供用于创建套接字的类来便于程序的网络通信.套接字(scoket)是两台主机之间逻辑连接的端点,可以用来发送和接收数据.
网络程序设计通常涉及一个服务器和一个或多个客户端,客户端向服务器发送请求,而服务器响应请求.客户端尝试建立与服务器的连接开始,服务器可能接受或拒绝这个连接.一旦建立连接,客户端和服务器就可以通过套接字进行通信.
当客户端尝试连接服务器时,服务器必须正在运行.服务器等待来自客户端的连接请求.
12345678910// 服务端 // 创建服务器套接字 final ServerSocket serverSocket = new ServerSocket(8000); // ...
Java基础-I/O流
参考文献
IO 多路复用
Java语言设计-基础篇(第8版)
Java核心技术 卷2 高级特性
Java IO Tutorials
I/O流
InputStream/Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流.
OutputStream/Writer: 所有的输出流的基类,前者是字节输出流,后者是字符输出流.
File类
File对象封装了文件或路径的属性,但是它既不包括创建文件,也不包括从(向)文件读(写)数据的方法.
文件输入和输出
PrintWriter
java.io.PrintWriter类可以用来创建一个文件并向文本文件写入数据.首先必须为一个文本文件创建一个PrintWriter对象.
123 final PrintWriter printWriter = new PrintWriter(new File(""));printWriter.println("");printWriter.close();
Scanner
java.util.Scanner类用来从控制台读取 ...
Java基础-BigDecimal使用
参考文献
BigDecimal概述
BigDecimal是Java在java.match包中提供的API类,主要用来对超过16位有效位的数进行精确的运算.
双精度浮点型变量double可以处理16位有效数,但在实际引用中,可能需要对更大或者更小的数进行运算和处理;
一般情况对于那些不需要精确计算精度的数字,可以直接使用Float和Double来处理,但是使用Float.valueOf(String)和Float.valueOf(String)会丢失经,所以面对需要精确计算的结果,则必须使用BigDecimal类来操作;
BigDecimal所创建的是对象,所以不能使用传统的+,-,*,/等运算符直接对对象进行数学运算,而必须调用其对应的方法,方法的参数也必须是BigDecimal的对象.
BigDecimal常用的构造函数
BigDecimal(int): 创建一个具有参数所指定整数值的对象
BigDecimal(double): 创建一个具有参数所指定双精度值的对象
BigDecimal(long): 创建一个具有参数所指定长整型数值的对象
BigDecimal( ...
Java基础-序列化
参考文献
面试官:Java序列化为什么要实现Serializable接口?我懵了
什么是序列化
序列化: Java中的序列化机制能够将一个实例化对象信息写入到一个字节流中(只序列号对象的属性值,而不会去序列化方法),序列化后的对象可用于网络传输,或者持久化到数据库,磁盘中.
反序列化: 需要对象的时候,在通过字节流中的信息来重构一个相同的对象.
Java中具体实现
Java中要使一个类可以序列化,实现java.io.Serializable接口是最简单的.
1234public class User implements Serializable { private static final long serialVersionUID = 1L;}
123456789@Datapublic class User implements Serializable { private static final long serialVersionUID = 1L; private String name; private S ...
Java基础-反射&&动态代理
参考文献
java动态代理实现与原理详细分析
Trail: The Reflection API
Spring CGLIB 动态代理子类导致的注解丢失
反射
获取Class对象的四种方式
知道具体类的情况下可以使用:
1Class klass = Person.class;
通过 Class.forName()传入类的全路径获取:
1Class klass = Class.forName("cn.holelin.Person");
通过对象实例instance.getClass()获取:
12Person o = new Person();Class klass = o.getClass();
通过类加载器xxxClassLoader.loadClass()传入类路径获取:
1ClassLoader.getSystemClassLoader().loadClass("cn.holelin.Person");
通过类加载器获取 Class 对象不会进行初始化,意味着不进行包括初始化等一系列步骤,静态代码块和静态对象不会得到执 ...
Java基础-泛型
参考文献
【对线面试官】今天来聊聊Java泛型
Java 基础 - 泛型机制详解
泛型
Java泛型这个特性是从JDK 1.5才开始加入的,因此为了兼容之前的版本,Java泛型的实现采取了“伪泛型”的策略,即Java在语法上支持泛型,但是在编译阶段会进行所谓的“类型擦除”(Type Erasure),将所有的泛型表示(尖括号中的内容)都替换为具体的类型(其对应的原生态类型),就像完全没有泛型一样.
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型).也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法.
引入泛型的意义在于:
适用于多种数据类型执行相同的代码(代码复用)
泛型类
123456789public class Test<T>{ private T var ; public T getVar(){ return var ; ...