一、增强for循环
x必须实现过Iterable接口
for(i in x){
}
二、自动封箱拆箱
byte - Byte
short - Short
int - Integer
long - Long
float - Float
double - Double
char - Character
boolean - Boolean
jdk5以后增加了自动封箱拆箱的机制,在必要时自动的进行 基本数据类型和其包装类的类型转换,方便了代码的开发。
三、静态导入
import xxxxx
import static xxxxx
四、可变参数
public void mx(int ...nums)
**一个函数中可变参数只能使用一次 且只能出现在函数的参数列表的最后一个位置
**可变参数也可以直接接收一个数组 非常的方便和灵活
五、枚举
枚举相当于是一个特殊的类 无法直接创建对象 只能有在枚举内部声明的固定个的值
本质上是一个 私有化了构造方法 的 抽象类 在内部创建这个类被final的对象 供外界使用
**枚举类可以包含属性
**枚举类也可以自己声明构造方法 必须是私有的
**枚举类也可以包含普通方法
**枚举类也可以包含抽象方法
所有的枚举类 都 继承自Enum类 所以自动就会具有Enum类中定义的方法
String name() //获取当前枚举项的名称
String ordinal() //获取当前枚举项在整个枚举中是第几个项 注意从0开始数
六、泛型
泛型就是不确定的类型
集合泛型
在没有泛型时,集合类时面向Object开发的,所有类型的数据都可以存入,同时所有对象存入集合后类型信息也就丢失了,需要在获取数据时进行强制类型转换,非常的不安全!
所有在jdk5版本中java引入了泛型机制,最早应用在集合类上,称之为集合泛型
**泛型的使用:可以两边没有 也可以一边有一边没有 也可以两边都有 但是一旦两边都有 必须一模一样 泛型中没有继承关系的概念!
List<String> list1 = new ArrayList<String>();
List list2 = new ArrayList();
List<String> list3 = new ArrayList();
List list4 = new ArrayList<String>();
//List<Object> list5 = new ArrayList<String>();//报错
//List<String> list = ArrayList<Object>();//报错
自定义泛型
方法上的泛型
方法上的泛型的作用范围是当前方法
方法上的泛型 需要先定义再使用
方法上的泛型通过尖括号 在方法的返回值前进行声明
泛型的名称可以随意的取 但是一般都取为一个大写字母 也可以在一个方法中定义多个泛型 只需要在尖括号中通过逗号分割依次声明就可以了
方法上的泛型 的 具体类型 是在方法被调用的时启动推测而知
类上的泛型
类上定义的泛型的作用范围是当前类的内部
类上定义的泛型 需要先定义再使用
类上的泛型通过尖括号 在类名后进行声明
泛型的名称可以随意的取 但是一般都取为一个大写字母 也可以在一个方法中定义多个泛型 只需要在尖括号中通过逗号分割依次声明就可以了
类上定义的泛型 需要在创建类的对象或引用时 明确的指定泛型的具体类型
注意,类上定义的泛型,不能在静态方法中使用,如果非要在静态方法上使用泛型,可以在该方法上自己定义自己使用。
**集合泛型其实一点都不特殊,本质上就是在集合类上定义的类上的泛型
上边界
泛型是一种不确定的类型 可以在使用时为其指定为任意类型 这种灵活的特性 使我们的程序更加的灵活 但是过于灵活可能也会带来问题 有时我们需要限定这种过于灵活的特点 此时可以使用上边界 在泛型定义时 通过extends关键字 限定 泛型 必须是指定类型 或其子孙类型
而如果不指定泛型的上边界,泛型的上边界默认为Object
==============
下边界
下边界通过super关键字来指定
限定泛型的取值为指定类型或其祖先类型
但是super不是用来在泛型定义时使用的,而是用在泛型通配符中
泛型通配符
泛型的通配符 使用在 类上泛型指定具体类型时 如果无法确定 泛型的具体取值 可以使用?来替代
而泛型通配符 可以通过 extends关键字声明?取值的上边界
==============
泛型的原理 - 泛型擦除:
.java -- 编译器 编译 --> .class --> jvm 运行
泛型只在编译阶段起作用 在编译的过程中 编译期 根据泛型的声明进行语法检查 在检查完成 真正将代码转换为.class文件的过程中 会将泛型相关的信息 进行擦除 所谓 的擦除 具体过程是 将所有的泛型替代为 其 上边界类型 并在必要的地方 加上必须的 类型强转 和 类型检查。所有 一个.java 编译为 .class之后 所有泛型的信息将会丢失 这个过程称之为 泛型的擦除。
七、注解
@Override
@Deprecated
@SuppressWarnings
注释:给人看的提示信息
注解:给程序看的提示信息
注解的定义:
声明一个注解的过程 和 声明一个接口非常的类似 通过@iterface来进行声明
声明的注解 还可以使用 元注解 来进行修饰 控制注解的行为特性
所谓的元注解 就是 用来修饰注解定义的注解
@Target - 控制被修饰的注解 可以在什么位置使用 如果不声明@Target 则该注解可以用在任意位置
@Retention - 控制注解被保留到什么时候
RetentionPolicy.SOURCE -- 该注解被保留到源码阶段 在编译的过程中该注解被删除 -- 这种注解 是给编译器看的 用来控制 编译器的行为的
RetentionPolicy.CLASS -- 该注解在源码中 和 编译后的.class中都有保留 但是 在.class被加载为字节码的过程中 被删除 -- 给类加载器看的 控制类加载器的行为
RetentionPolicy.RUNTIME -- 该注解 在源码中 .class中 和 内存的字节码中 都可以找到 -- 这种注解 在内存的字节码中存在 也就意味着 程序员 可以通过反射技术 得到注解的信息 来控制程序的运行 这也是 我们最常用的级别
@Documented -- 控制该注解是否会被文档提取工具提取为文档信息 如果不写这个注解 默认 在生成的文档中 是没有该注解信息的
@Inherited -- 控制注解是否具有继承性 如果不写 默认注解不会继承
注解中还可以声明属性
注解中声明属性的过程 非常类似于 在接口中定义方法 只不过 注解中声明的属性 必须是public的或者不写访问权限修饰符 默认就是public的。
注解中的属性 只能是 八种基本数据类型 Class类型 String类型 其他注解类型 及 这些类型的一维数组
注解中声明的属性 需要在使用注解时 为其赋值 赋值的方式 就是使用注解时 在注解后跟一对小括号 在其中 通过 属性名=属性值 的方式 指定属性的值
也可以在声明注解时 在注解的属性后 通过default关键字 声明属性的默认值 声明过默认值的属性 可以在使用注解时 不赋值 则默认采用默认值 也可以手动赋值 覆盖默认值
如果属性是 一维数组类型 而 在传入的数组中 只有一个值 则包括数组的大括号可以省略
如果注解的属性 只有一个需要赋值 且该属性的名称叫做value 则在使用注解时 value= 可以不写
反射注解:
在Class Method Field Constructor..等类上 都有获取注解信息的方法
Annotation[] getAnnotations() //获取所有注解
<A extends Annotation> A getAnnotation(Class<A> annotationClass) //获取指定注解
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) //是否在该元素上 标注过指定注解
可以通过这些方法 反射得到 类上 方法 属性 构造器..等位置上标注过的注解 从而 通过 是否有注解 或 注解上属性的取值不同控制程序的运行过程。
**只有@Retention 是 RetentionPolicy.RUNTIME级别的注解才可以被反射
**注解常用作 轻量级的配置 在后续学习的框架中 有非常广泛 而 灵活的运用
八、动态代理
改变已有对象身上不喜欢的方法
继承
只能在对象还未创建之前 就继承 直接创建的是子类才可以改变方法
如果已经有对象创建出来了 继承并重写 对该对象无作用
装饰
装饰设计模式可以改变 已有对象身上的方法 但是编写的方式比较麻烦 特别是原来的类 方法比较多的情况下 冗余的代码非常的多
动态代理
java中为了实现代理 专门提供了一个 java.lang.reflect.Proxy类 帮我们生成代理者
通过调用Proxy的 static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 就可以为原有对象生成对应的代理对象了
之后不允许直接使用被代理对象,所有的操作都找代理对象,而调用代理对象的任何方法都会走到InvocationHandler中的invoke方法中 可以在invoke方法中编写代码 处理代理的逻辑 对于不想改造的方法 调用原有对象身上的方法 对于想改造的方法 根据自己的意愿改造
九、单例设计模式
单例设计模式 主要的目的是 实现某个类只有一个对象 效果
懒汉式
将类的构造方法私有化
在类内部提供静态的当前类的对象 最开始为null
当有人调用获取对象的方法时 临时判断 保存在类的内部的对象是否为null 如果为null 就赋值后返回 如果不为null 直接返回
这种方式在多线程场景下有多线程并发安全问题的风险 需要用synchronized来同步
效率比较低下
饿汉式
将类的构造方法私有化
在类的内部提供静态的当前类的对象 直接就赋值
当有人调用获取对象的方法时 直接返回该对象
效率比较高 但是 在类加载 单对象还未被使用时 就创建了对象 比较占用控制
推荐用这种方式