Java知识点梳理——核心语言特性
第一部分:核心语言特性
一、反射
1、反射在框架中的应用
2、反射实战-应用场景和总结
二、泛型
1、泛型的规则与类型擦除
什么叫类型擦除呢?简单的说就是,类型参数只存在于编译期,在运行时,Java 的虚拟机 ( JVM ) 并不知道泛型的存在。
上面的代码有两个不同的 ArrayList:ArrayList
2、类型和限制两种泛型的通配符讲解
3、在API设计时使用泛型的方式(自定义泛型类、泛型接口、泛型方法)
https://blog.csdn.net/ldw201510803006/article/details/80450081
三、注解
1、理解注解给Java带来的优雅之道
2、理解注解的本质和原理
3、理解注解定义和应用场景、实现自定义注解
https://blog.csdn.net/zt15732625878/article/details/100061528
4、掌握元注解和预置注解
https://www.cnblogs.com/peida/archive/2013/04/24/3036689.html
5、注解和反射在框架中的实战
四、语言新特性
1、在函数式接口上更好的使用Lambda表达式
(1)函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。可以在接口前使用注解@FunctionalInterface检查该接口是否为函数式接口。
(2)@FunctionalInterface:检查该接口是否为函数式接口。该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错
(3)函数描述符:函数式接口的抽象方法的签名基本上就是Lambda表达式的签名,我们将这种抽象方法称之为函数描述符。
(4)Lambda表达式:
A) 在Java8中,引入了一个新的操作符"->",该操作符将lambda表达式拆分成两个部分:lambda表达式的参数列表,位于"->"操作符左边,lambda表达式所执行的功能,即lambda体。位于"->"操作符右边。
常见的lambda表达式的语法格式:
a1) 函数式接口中的方法无参数,例子如下:() ->{//do something},若方法体只有一个语句,return和花括号都可以省略不写。
a2) 函数式接口中的方法有参数,例子如下:(int x, int y) -> {//do something},表达式中参数的类型可以不写,编译器可以通过上下文推断出其类型,上面的代码可以简化如下:(x, y) ->{do something}
a3) 如果只有一个参数,参数列表的括号可以省略,例子如下:x ->{//do something}
2、优雅的使用Stream操作数据的切片、筛选、过滤
public class Test3 {
public static List<User> users = Arrays.asList(
new User("lzj", 25),
new User("zhangsan", 26),
new User("lisi", 30),
new User("wanger", 18),
new User("zhaowu", 29),
new User("zhaowu", 29));
public static void main(String[] args) {
Stream<User> stream = users.stream() //创建通道流
.filter((x) ->
x.getAge()>20)//过滤
.distinct(); //去重
stream.forEach(System.out::println);
System.out.println(users);
}
}
filter---接收Lambda,从流中排除某些元素
limit---截断流,使其元素不超过给定的数量
skip(n)---跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回一个空流,与limit(n)互补
distinct---筛选,通过流所生成元素的hashCode( )和equals( )去除重复元素
3、在大数据量下归类与计算利器Map/Reduce
MapReduce 是 Hadoop的核心组成,是专用于进行数据计算的。重点掌握实现 MapReduce 算法的步骤,掌握 map、reduce 函数的特点、如何写函数。
五、核心类的使用
1、Spring框架中的核心类剖析
(1)spring核心类:
A) BeanFactory:产生一个新的实例,可以实现单例模式
B) BeanWrapper:提供统一的get及set方法
C) ApplicationContext:提供框架的实现,包括BeanFactory的所有功能
(2)核心组件:Bean、Context、Core
A) Bean组件
Bean 组件在 Spring 的 org.springframework.beans 包下。这个包下的所有类主要解决了三件事:Bean 的定义、Bean 的创建以及对 Bean 的解析。对 Spring 的使用者来说唯一需要关心的就是 Bean 的创建,其他两个由 Spring 在内部帮你完成了,对你来说是透明的。Spring Bean 的创建时典型的工厂模式,他的顶级接口是 BeanFactory,下图是这个工厂的继承层次关系:
B) Context 组件
Context 在 Spring 的 org.springframework.context 包下,他实际上就是给 Spring 提供一个运行时的环境,用以保存各个对象的状态。下面看一下这个环境是如何构建的。ApplicationContext 是 Context 的顶级父类,他除了能标识一个应用环境的基本信息外,他还继承了五个接口,这五个接口主要是扩展了 Context 的功能。下面是 Context 的类结构图:
从上图中可以看出 ApplicationContext 继承了 BeanFactory,这也说明了 Spring 容器中运行的主体对象是 Bean,另外 ApplicationContext 继承了 ResourceLoader 接口,使得 ApplicationContext 可以访问到任何外部资源,这将在 Core 中详细说明。
ApplicationContext 的子类主要包含两个方面:
a) ConfigurableApplicationContext 表示该 Context 是可修改的,也就是在构建 Context 中用户可以动态添加或修改已有的配置信息,它下面又有多个子类,其中最经常使用的是可更新的 Context,即 AbstractRefreshableApplicationContext 类。
b) WebApplicationContext 顾名思义,就是为 web 准备的 Context 他可以直接访问到 ServletContext,通常情况下,这个接口使用的少。
总体来说 ApplicationContext 必须要完成以下几件事:
a) 标识一个应用环境
b) 利用 BeanFactory 创建 Bean 对象
c) 保存对象关系表
d) 能够捕获各种事件
C) Core 组件
Core 组件作为 Spring 的核心组件,他其中包含了很多的关键类,其中一个重要组成部分就是定义了资源的访问方式。这种把所有资源都抽象成一个接口的方式很值得在以后的设计中拿来学习。下面就重要看一下这个部分在 Spring 的作用。下图是 Resource 相关的类结构图:
从上图可以看出 Resource 接口封装了各种可能的资源类型,也就是对使用者来说屏蔽了文件类型的不同。对资源的提供者来说,如何把资源包装起来交给其他人用这也是一个问题,我们看到 Resource 接口继承了 InputStreamSource 接口,这个接口中有个 getInputStream 方法,返回的是 InputStream 类。这样所有的资源都被可以通过 InputStream 这个类来获取,所以也屏蔽了资源的提供者。另外还有一个问题就是加载资源的问题,也就是资源的加载者要统一,从上图中可以看出这个任务是由 ResourceLoader 接口完成,他屏蔽了所有的资源加载者的差异,只需要实现这个接口就可以加载所有的资源,他的默认实现是 DefaultResourceLoader。
下面看一下 Context 和 Resource 是如何建立关系的?首先看一下他们的类关系图
从上图可以看出,Context 是把资源的加载、解析和描述工作委托给了 ResourcePatternResolver 类来完成,他相当于一个接头人,他把资源的加载、解析和资源的定义整合在一起便于其他组件使用。Core 组件中还有很多类似的方式。
2、Google开源Java工具库Guava+Apache Commons的核心类剖析
(1)guava: https://blog.csdn.net/Munger6/article/details/98068931
(2) Apache4 common:
组件 | 功能介绍 |
---|---|
BeanUtils | 提供了对于JavaBean进行各种操作,克隆对象,属性等等. |
Betwixt | XML与Java对象之间相互转换. |
Codec | 处理常用的编码方法的工具类包 例如DES、SHA1、MD5、Base64等. |
Collections | java集合框架操作. |
Compress | java提供文件打包 压缩类库. |
Configuration | 一个java应用程序的配置管理类库. |
DBCP | 提供数据库连接池服务. |
DbUtils | 提供对jdbc 的操作封装来简化数据查询和记录读取操作. |
java发送邮件 对javamail的封装. | |
FileUpload | 提供文件上传功能. |
HttpClien | 提供HTTP客户端与服务器的各种通讯操作. 现在已改成HttpComponents |
IO | io工具的封装. |
Lang | Java基本对象方法的工具类包 如:StringUtils,ArrayUtils等等. |
Logging | 提供的是一个Java 的日志接口. |
Validator | 提供了客户端和服务器端的数据验证框架. |
3、String类的只读设计和值传递
String被设计成不可变的主要目的是为了安全和高效。
(1)字符串常量池的需要字符串
常量池是Java堆内存中的一个特殊的存储区域,当创建一个String对象时,加入此字符串值已经在常量池中,则不会创建新的对象,而是引用已经存在的对象。如下代码所示,将会在堆内存中只创建一个实际的String对象
String s1 = "abcd";
String s2 = "abcd";
(2)允许String对象缓存HashCode
Java中String对象的哈希吗被频繁的使用,比如在HashMap等容器中。String类的不变性保证了hash码的唯一性,因此可以放心地进行缓存。
(3)安全性
字符串被许多的Java类库用来当做参数,例如网络连接地址URL、文件路径、反射机制所需要的String参数等,假如String不是固定不变的,将会引起各种安全隐患。不可变对象天生就是线程安全的。
4、JDK工具包中的核心类剖析
(1)java.lang:包含一些Java语言的核心类,如String、Math、Integer、System和Thread,提供常用功能。
(2)java.awt:包含了构成抽象窗口工具集(abstract window toolkits)的多个类,这些类被用来构建和管理应用程序的图形用户界面(GUI)。
(3)java.applet:包含applet运行所需的一些类。
(4)java.net:包含执行与网络相关的操作的类。
(5)java.io:包含能提供多种输入/输出功能的类。
(6)java.util:包含一些实用工具类,如定义系统特性、使用与日期日历相关的函数。
注:java.lang这个包会自动被导入,对于其中的类,不需要使用import语句来做导入。