目录
枚举
我们首先来看一下枚举是怎么用的?下面是一个简单的例子。
package www.like.java;
enum Color{
RED,YELLOW,BLUE
}
public class exercise1 {
public static void main(String[] args) {
System.out.println(Color.BLUE);
}
}
Enum类
enum并不是一种新的结构,它只是对类型的一种包装:使用enum关键字定义的枚举类实际上是Class定义的类,继承了java.lang.Enum。
Enum类中存在两大属性:
name:枚举对象名称
ordinal:枚举对象的数字下标
Enum类有以下方法:
1.构造方法:
2.取得枚举名字:
3.取得枚举序列号:
除了一个一个的输出之外,在枚举操作中还有一个方法可以取得所有的枚举数据:values()返回的是一个枚举的对象数组。
例:取出枚举的所有数据
package www.like.java;
enum Color{
RED,YELLOW,BLUE
}
public class exercise1 {
public static void main(String[] args) {
for(Color data:Color.values()){
System.out.println(data);
}
}
}
问题:请解释enum与Enum的区别。
enum是一个关键字,使用enum定义的枚举类本质上就相当于一个类继承了Enum这个抽象类而已。
枚举中定义其他结构
枚举等同于多例类,多例设计是在类中产生的,类中还包含属性,方法。所以在enum中,也可以定义一些属性和方法。
但是在定义属性或方法的时候,要注意以下几点:
- 枚举中若定义构造方法,构造方法必须私有化。(枚举类相当于多例类,多例类外部无法产生对象,枚举类外部也无法产生对象,所以构造方法必须用private封装)
- 枚举类中若定义其他结构,枚举对象声明必须放在首行。
例:枚举中定义其他结构
package www.like.java;
enum Color{
RED("红"),YELLOW("黄"),BLUE("蓝"); //如果定义其他结构,枚举对象放在首行
private String data;
private Color(String data) { //构造方法私有化
this.data = data;
}
@Override
public String toString() {
return this.data;
}
}
public class exercise1 {
public static void main(String[] args) {
System.out.println(Color.RED);
System.out.println(Color.YELLOW);
System.out.println(Color.BLUE);
}
}
枚举实现接口
枚举可以实现接口,这样每个枚举对象就变成了接口对象。
package www.like.java;
interface IColor{
public String getColor();
}
enum Color implements IColor{
RED("红"),YELLOW("黄"),BLUE("蓝"); //如果定义其他结构,枚举对象放在首行
private String data;
private Color(String data) { //构造方法私有化
this.data = data;
}
@Override
public String toString() {
return this.data;
}
@Override
public String getColor() {
return this.data;
}
}
public class exercise1 {
public static void main(String[] args) {
IColor color = Color.BLUE;
System.out.println(color);
}
}
注解
@override 准确覆写
当子类覆写父类方法时,此注解检查覆写的方法是否正确声明,只有满足覆写方法要求才会编译通过,否则编译出错。
这种注解非常常见。
@Deprecate 过期声明
建议用户不使用原有的类或方法时,可以在类或方法上@Deprecated表示在当前版本中不建议使用。
我们可以看到,如果使用了过期声明的类或方法,虽然可以使用,但是在该类或属性上加一个横杠。
@SuppressWarnings 压制警告
调用某些操作可能产生问题的时候,会出现警告信息,但警告信息并不是异常。如果不想出现这些警告,就可以使用压制警告。
接口定义加强
JDK1.8之后,接口中允许出现以下两类方法:
a. 使用default定义的普通方法,需要通过接口对象来调用。
b. 使用static定义的静态方法,直接使用接口名调用。
Lambda表达式
要想使用函数式编程,有一个前提,接口必须只有一个方法,如果存在两个以上的方法,无法使用函数式编程。
如果现在某个接口就是为了函数式编程而生的,在定义时只能存在一个方法,因此有一个新的注解@FunctionalInterface,此注解会检查接口中是否只存在一个抽象方法,存在两个抽象方法以上,编译报错。
例:函数式编程
package www.like.java;
//函数式编程接口,只允许存在一个方法
@FunctionalInterface
interface IMessage{
void print();
}
public class exercise1 {
public static void main(String[] args) {
//函数式编程的使用
IMessage message = ()-> System.out.println("hello world");
message.print();
}
}
语法:
方法体只有一行代码时:
(方法参数) -> 具体的方法体实现
当方法有返回值时,单行代码的Lambda表达式,可以省略return语句。
当方法体有多行代码时:
(方法参数) -> {
……
[return 语句];
};
注意:最后的分号不能忘记。
package www.like.java;
@FunctionalInterface
interface IAdd{
int add(int x, int y);
}
public class exercise1 {
public static void main(String[] args) {
IAdd iadd = (p1,p2)->{
int p3 = (p1+10)*p2;
return p3;
} ;
System.out.println(iadd.add(10,20));
}
}
方法引用
方法引用的本质就是给方法起了个别名。
方法引用与lamdba表达式配合使用。
方法引用有四种形式:
引用类中静态方法
类名称 :: 静态方法名称
package www.like.java;
@FunctionalInterface
interface IUtil<P,R>{
R switchPara(P p);
}
public class exercise1 {
public static void main(String[] args) {
IUtil<Integer,String> util = String::valueOf;
//相当于调用String.valueOf()
String str = util.switchPara(10);
//检验数字是否成功转化为字符串
System.out.println(str.startsWith("1"));
}
}
引用某个对象的方法
实例化对象::普通方法
package www.like.java;
@FunctionalInterface
interface IUtil<P>{
P switchPara();
}
public class exercise1 {
public static void main(String[] args) {
//相当于调用了"hello".toUpperCase
IUtil<String> util = "hello"::toUpperCase;
System.out.println(util.switchPara());
}
}
调用类中普通方法
类名称::普通方法名
package www.like.java;
@FunctionalInterface
interface IUtil<R,P>{
R compare(P p1,P p2);
}
public class exercise1 {
public static void main(String[] args) {
IUtil<Integer,String> util = String::compareTo;
System.out.println( util.compare("zhang","li"));
}
}
引用类中的构造方法
类名称::new
package www.like.java;
class Person{
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "姓名:"+this.name+" 年龄:"+this.age;
}
}
@FunctionalInterface
interface IUtil<R,PN,PA>{
R createPer(PN p1, PA p2);
}
public class exercise1 {
public static void main(String[] args) {
IUtil<Person,String,Integer> util = Person::new;
System.out.println(util.createPer("张三",19));
}
}