文章目录
Java新特性(二)
枚举
JDK1.5后引入的一个主要新功能
利用枚举类型可以简化多例设计模式(一个类固定产生几个对象)
枚举可以像普通类一样定义属性、构造方法、实现接口
枚举的概念
枚举可以用来定义一组可以使用的类对象,这样在使用时只能通过固定的几个对象进行类的操作
java1.5引入关键字enum
enum Color{
RED,BLUE,GREEN; //代表实例化对象
}
public class Test{
public static void main(String args[]){
Color red = Color.RED;//直接取得枚举对象
System.out.println(red);
}
}
需要时调用定义好的对象就好了
如果使用多例设计模式会麻烦的一批
使用多利设计模式的时, 必须保证构造方法要封装
枚举实现了多例设计模式, 故枚举对象时字母全部大写
枚举中可以定义方法、属性、甚至其他结构
Enum本身是一个抽象类
严格来讲,枚举只是类结构的加强而已,在java中使用enum相当于继承了java.lang.Enum类
完全定义形式如下
public abstract class Enum<E extends Enum<E>> extends Object implements Comparable<E>, Serializable
抽象类在使用时必须被子类继承,
Enum的构造方法使用protected封装
enum是用于定义枚举类型的关键字
每一个使用enum定义的枚举对象都表示一个类默认继承了Enum类
枚举对象的序号都是按照定义顺序自动生成的
定义其他结构
枚举类型属于多例设计模式,类中包含属性、方法、构造方法
注意两点:
-
枚举中定义的构造方法不能使用public声明,如果没有无参构造,要手工调用构造传递参数
-
枚举对象必须要放在首航,随后才可以定义属性、构造、普通方法等结构
扩充枚举功能
enum Color{
RED("红色"), GREEN("绿色"), BLUE("蓝色"); //定义枚举对象,必须写在首行
private String title;
private Color(String title){ //构造方法,不能使用public声明
this.title = title
}
public String toString(){ //覆写toString()
return this.title;
}
}
public class Test{
public static void main(String args[]){
for(Color c:Color.values()){ //取得全部枚举对象
System.out.println(c+",");
}
}
}
枚举实现接口
- 枚举中覆写方法,所有枚举对象都是IMessage接口的实例
interface IMessage{
public String getTitle();
}
enum Color implements IMessage{ //枚举来实现接口
RED("红色"), GREEN("绿色"), BLUE("蓝色");
private String title;
private Color(String title){ //构造方法,不能使用public声明
this.title = title
}
public String toString(){ //覆写toString()
return this.title;
}
public String getTitle(){
return this.title;
}
}
public class Test{
public static void main(String args[]){
IMessage msg Color.RED;
System.out.println(msg.getTitle());
}
}
- 在每个枚举对象上使用内部匿名类的方式定义了接口的实现操作
interface IMessage{
public String getTitle();
}
enum Color implements IMessage{ //枚举来实现接口
RED("红色"){ //枚举类型定义
public String getTitle(){
return this+"-red";
}
}
GREEN("绿色"){
public String getTitle(){
return this+"-green";
}
}
BLUE("蓝色"){
public String getTitle(){
return this+"-blue";
}
}
private String title;
private Color(String title){ //构造方法,不能使用public声明
this.title = title
}
public String toString(){ //覆写toString()
return this.title;
}
}
public class Test{
public static void main(String args[]){
IMessage msg Color.RED;
System.out.println(msg.getTitle());
}
}
定义抽象方法再覆写
如果定义了一个抽象对象吗,那么枚举中每一个对象都必须覆盖该方法
interface IMessage{
public String getTitle();
}
enum Color implements IMessage{ //枚举来实现接口
RED("红色"){ //枚举类型定义
public String getTitle(){
return this+"-red";
}
}
GREEN("绿色"){
public String getTitle(){
return this+"-green";
}
}
BLUE("蓝色"){
public String getTitle(){
return this+"-blue";
}
}
private String title;
private Color(String title){ //构造方法,不能使用public声明
this.title = title
}
public String toString(){ //覆写toString()
return this.title;
}
public abstract String getTitle(); //抽象方法
}
public class Test{
public static void main(String args[]){
IMessage msg Color.RED;
System.out.println(msg.getTitle());
}
}
枚举的实际应用
可以和case switch一起使用
开始只能用int 和char
JDK1.5之后可以用enum
JDK1.7以后可以用String
switch可以直接判断枚举类型
如果习惯用枚举就使用,不习惯不如不用
Annotation
JDK1.5之后引入的注解技术
可以回避面向对象中覆写名称固定的问题
其直观描述也适合开发者进行程序的编写
如果想开发Annotation需要容器支持才能在正常开发非常复杂
java SE中三种基础Annotation:
@Override @Deprecated @SuppressWarnings
软件开发设计模式:
-
将所有与配置相关的内容涵盖直接写到代码
代码编写方便
如果服务器地址变更或者信息增多,代码维护困难
-
将配置与程序代码独立,即程序运行时根据配置文件进行操作
代码维护方便,当信息变更时直接修改配置文件,程序不需要改
当配置信息增多后,配置文件也相应增多程序维护困难
-
配置信息对用户无用,将配置信息写回程序里
不需要单独定义配置文件,可以减少代码量
需要容器支持,开发难度高
一般使用方法二三
以下注解都写在方法前面一行
准确的覆写:@Override
进行方法覆写时,为了保证子类所覆写的方法的确时父类定义过的方法,可以加上@Override注解
覆写错误也可以在编译时检查出来,如果不写覆写正确没问题,但是覆写错误无法验证
声明过期的操作:@Deprecated
用来标注在后期版本中不建议使用的方法
可以继续使用,但是不建议用
尽量避免使用这样的操作
压制警告:@SuppressWarnings
如果使用了不安全的操作,程序在编译过程中会出现安全警告
使用这个注释可以压制所有出现警告的信息
接口加强定义
接口是解决多继承问题的,接口由全局常量和抽象方法构成
JDK1.8以后可以在接口中定义普通方法(default)和静态方法(static)
接口中的普通方法必须使用default来声明
注意:开发初期不要考虑定义static方法设计
还是以传统的方式为基础开发
如果后期的确有需要再声明default和static
Lambda表达式
JDK1.8引入新特性
Lambda表达式是指应用在单一抽象方法(Single Abstract Method)SAM接口环境下的一种简单定义变化形式
用于解决匿名内部类定义复杂的问题
基本Lambda表达式操作
interface IMessage{
public void print()
}
public class Test{
public static void main(String args){
fun(()->System.out.println("WDNMD")); //lambda表达式
}
public static void fun(IMessage msg){
msg.print();
}
}
()->System.out.println(“WDNMD”)就是lambda表达式
它的作用是覆写IMassage的print()
相当于匿名内部类的操作
普通的匿名内部类如下:
interface IMessage{
public void print()
}
public class Test{
public static void main(String args){
fun(new IMessage(){
@Override
public void print(){
System.out.println("WDNMD");
}
}); //匿名内部类
}
public static void fun(IMessage msg){
msg.print();
}
}
可以看出lambda表达式简化很多
Lambda表达式的语法:
(参数)->方法体
在lambda表达式中已经明确要求是在接口上进行的一种操作
接口中只允许定义一个抽象方法
为了辨认出Lambda表达式所使用的接口, 可以给接口使用
@FunctionallInterface
注解声明, 将他写在接口前
理论上来讲,接口只有一个抽象方法,不写这个注解没有区别,但是还是建议写上为好
lambda表达式三种形式
(params)->expression; 方法主体为一个表达式
(params)->statment; 方法主体是一行执行代码
(params)->{statments} 方法主题是多行执行代码
匿名内部类final使用问题
1.8以前内部类要访问的方法的参数或者方法中定义的变量需要final进行定义
1.8以后取消了这个限制, 这是为Lambda表达式准备的
Lambda\表达式也可以传递可变参
方法引用
原来Java中可以对对象引用,实现不同对象名称操作一块堆内存空间
JDK1.8开始,方法也可以进行引用
相当于给方法定义了别名
引用静态方法: 类名称::static方法名称
医用某个对象的非方法: 实例化对象::普通方法
引用特定类型的方法: 特定类::普通方法
引用构造方法: 类名称::new
这里主要是看这些方法是否涉及到一个具体实例化对象
如果仅仅和一个具体的实例化对象操作就一定要使用实例化对象
如果关于多个对象或者产生了返回实例化对象,那就用类名
内建函数式接口
JDK1.8提供了java.util.function
有四个核心函数接口
-
功能型接口(Function)
@FunctionInterface public interface Function<T,R>{ public R apply(T t); } //此接口需要一个参数,返回一个处理结果
-
消费型接口(Consumer)
@FunctionInterface public interface Consumer<T>{ public void accept(T t); }//此接口接受一个参数但是不返回处理结果
-
供给型接口(Sipplier)
@FunctionInterface public interface Supplier<T>{ public T get(); }//此接口不接受参数,返回结果
-
断言型接口(Predicate)
@FunctionInterface public interface Predicate<T>{ public boolean test(T t); }//此接口做判断用