【总结篇】Java5新特性总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sun8112133/article/details/89133616

版权声明:本文为 小异常 原创文章,非商用自由转载-保持署名-注明出处,谢谢!
本文网址:https://blog.csdn.net/sun8112133/article/details/89133616








一、自动装箱、拆箱

1、自动装箱、拆箱概述

自动装箱、拆箱指的是Java中基本数据类型与其对应的引用类型的自动转换。分别对应以下:

byte → Byte

short → Short

char → Character

int → Integer

long → Long

float → Float

double → Double

boolean → Boolean

2、自动装箱、拆箱好处

代码简洁,不容易出错。

3、使用方式

1)自动装箱

基本数据类型自动转为包装类型(如:int --> Integer)。

2)自动拆箱

包装类自动转为基本类型(如:Integer --> int)。

4、注意事项

在遍历的过程中,不能对集合或数组中的元素进行增删改操作。

5、应用

1)自动装箱

Integer i = 10;   // 相当于 Integer i = new Integer(10);

2)自动拆箱

Integer i = 10;
int a = i;    // 相当于 int a = i.intValue();


二、增强For循环

1、增强For循环概述

增强For循环是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是个迭代器,所以在遍历的过程中,不能对集合中的元素进行增删改操作。

2、增强For循环的好处

代码简洁,不容易出错,不用考虑集合中的下标。

3、使用方式(语法格式)

for (元素类型 变量名 : 集合/数组) {
	// 可以直接使用变量
}

4、注意事项

在遍历的过程中,不能对集合或数组中的元素进行增删改操作。

5、应用场景

List<String> list = new ArrayList<>;
list.add("hello");
list.add("world");
for (String s : list) {
	System.out.println(s);
}


三、可变参数

1、可变参数概述

可以变化的参数。它其实就是一个数组。

2、可变参数好处

1)定义方法的时候不知道该定义多少个参数。

2)参数类型相同时,把重载方法合并到了一起。

3、使用方式(语法格式)

[修饰符] 返回值类型 方法名(数据类型... 变量名)

4、注意事项

1)这里的变量其实是一个数组。

2)如果一个方法有可变参数,并且有多个参数,那么可变参数必须是最后一个。

5、应用场景

public static void main(String[] args) {
	int sum = sum("sum: ",1,2);    // 3
	sum = sum("sum: ",1,2,3);      // 6
	sum = sum("sum: ");            // 0
	System.out.println("sum: " + sum);
}


四、静态导入

1、静态导入概述

静态导入是导入类中的静态成员。如果有多个同名的静态成员,容易产生冲突,所以在开发中一般不用。

2、静态导入好处

可以直接在类中使用导入后的静态成员,不需要再加类名前缀。

3、使用方式(语法格式)

import static 包名.类名.静态成员名;

4、注意事项

成员必须是静态的。

5、应用场景

import static java.lang.Math.PI;
import static java.lang.Math.abs;
public class Demo {
    public static void main(String[] args) {
    	System.out.println("PI: " + PI);    // PI: 3.141592653589793
    	System.out.println("-5的绝对值:" + abs(-5));  // -5的绝对值:5
    }
}


五、枚举

1、枚举概述

是指将变量的值一一列出来,变量的值是有限个的。(举例:一周只有7天,一年只有12个月等。)当枚举只有一个成员时,则可以作为一种单例模式的实现方式。

枚举类在编译后,实际上是转化为一个继承了 java.lang.Enum类 的实体类。

2、枚举好处

简洁明了。

3、常用方法

int ordinal()

获取当前枚举项的编号(从0开始)。

int compareTo(E e)

比较当前枚举项与指定枚举项的编号(当前枚举项 - 指定枚举项)

String name()

获取当前枚举项的名称。

T valueOf(String name)

通过枚举项名获取枚举项。

values()

JDK文档没有,遍历枚举类中的所有枚举项。

4、注意事项

1)定义枚举类要用关键字 enum;

2)所有枚举类都是Enum类的子类;

3)枚举项必须在第一行,以逗号分隔,最后一个枚举项后的分号可以省略。若枚举项后有其他的东西,这个分号就不能省略;

4)枚举类可以有构造器,但必须是private的,它默认的也是private的。

5)枚举类也可以有抽象方法,但是枚举项必须重写该方法。

6)枚举可以在switch语句中使用。(1.5版本可以接收枚举,1.7版本可以接收字符串)

5、应用场景

1)自定义枚举类

public class Number {
    private String name;
    private Number(String name) {
    	this.name = name;
    }
    public static final Number ONE = new Number("一");
    public static final Number TWO = new Number("二");
    public static final Number THREE = new Number("三");
}

2)使用enum来创建枚举类

public enum Number {
    ONE("一"), TWO("二"), THREE("三");
    private String name;
    private Number(String name) {
    	this.name = name;
    }
}

3)实现接口的枚举类(相当于让每个枚举项重写抽象方法)

public enum Number implements AutoCloseable {
    ONE("一") {
        public void close() {
        	System.out.println("one关闭");
        }
    }, TWO("二") {
    	public void close() {
    		System.out.println("two关闭");
    	}
    }, THREE("三") {
   		public void close() {
    		System.out.println("three关闭");
    	}
    }
}


六、泛型

1、泛型概述

泛型是一种广泛的类型,把明确数据类型的工作提前到了编译时期。

分类: 泛型类、泛型方法、泛型接口。

2、泛型好处

1)保证数据类型的安全性,避免强制类型转换的问题,简化代码的书写。 String str = list.get(i);

2)将运行时的问题提前到了编译期间。

3、使用方式

1)泛型类

格式: [修饰符] class 类名<泛型类型1,...> ==> public class Student<T> { }

2)泛型方法

格式: [修饰符] <泛型类型> 返回类型 方法名(泛型类型 变量名) ==> public <E> void eat(E e) { }

3)泛型接口

格式: public interface 接口名<泛型类型1,...> ==> public interface Inter<T> { }

4)泛型通配符 <?>,任意的Java类。

格式1(上限通配符): <? extends E>

只能是E及其子类。【?~E】

List<? extends Man> list = new ArrayList<Man>();
List<? extends Man> list = new ArrayList<Boy>();

读数据: 【看上限】上限类型为Man类型(不管该list如何赋值,里面存放的元素一定是Man类型) Man m = list.get(0);

写数据: 【看下限】没有明确下限类型(编译器并不能准确的给出能接收的类型)

​ 只能接收null值,因为null值可以是任意类型。 list.add(null);

格式2(下限通配符): <? super E>

只能是E及其父类。【E~?】

List<? super Man> list = new ArrayList<Man>();
List<? super Man> list = new ArrayList<People>();

读数据: 【看上限】没有明确上限类型(编译器并不能准确给出能接收的具体类型),

但能确定存放的是Object类型,所以 上限默认为Object类型。 Object obj = list.get(0);

写数据: 【看下限】下限为Man类型(可以保证集合中的元素一定是Man类型,所以Man的子类元素也可以存放)。

4、注意事项

1)如果不使用泛型通配符,那么前后的泛型必须一致,或者后面的泛型可以不写(Java7新特性之菱形泛型)

List<String> list = new ArrayList<>();

2)泛型类必须是引用数据类型(类、接口、数组)。

5、应用场景

1)普通用法

List<String> list = new ArrayList<>;

2)泛型类

public class Tool<T> {
	private T name;
	public void setName(T name) {
		this.name = name;
	}
	public T getName() {
		return name;
	}
}

3)泛型方法

public clas Tool<T> {
	private T name;
	public void setName(T name) {
		this.name = name;
	}
	public T getName() {
		return name;
	}
	// 方法泛型最好与类的泛型一致,如果不一致,需要在方法上声明该类型
	public <E> void show(E e) {
		System.out.println(e);
	}
	// 静态方法必须声明自己的泛型,注:此时的T和类上的T不是同一个类型
	public static <T> void print(T t) {
		System.out.println(t);
	}
}

4)泛型接口

interface Inter<T> {
	public void show(T t);
}
// 第一种方式:推荐使用这种
class Demo implements Inter<String> {
	@Override
	public void show(String t) {
		System.out.println(t);
	}
}
// 第二种方式:没有必要在实现接口的时候给自己类加泛型
class Demo<T> implements Inter<T> {
	@Override
	public void show(T t) {
		System.out.println(t);
	}
}

5)泛型通配符:

很多时候都是用它来当作方法中的形参。开发时我们都需要遵循PECS法则(“Producer Extends, Consumer Super”),也就是:

如果参数化类型表示一个生产者,就使用 <? extends T>

如果参数化类型表示一个消费者,就使用 <? super T>

A. 基本用法:

class People {
	// 人
}
class Man extends People {
	// 男人
}
class Woman extends People {
	// 女人
}
class Boy extends Man {
	// 男孩
}
 
main {
	List<? extends Man> list = null;
	list = new ArrayList<Man>();
	list = new ArrayList<Boy>();
	list = new ArrayList<People>();   // 编译错误
	Man m = list.get(0);
	list.add(null);
	list.add(new Man());   // 编译错误
	///////////////////////////////////////////////////
	List<? super Man> list = null;
	list = new ArrayList<Man>();
	list = new ArrayList<People>();
	list = new ArrayList<Boy>();    // 编译错误
	Object obj = list.get(0);
	list.add(new Man());
	list.add(new Boy());
	list.add(new People());   // 编译错误
}

B. 应用场景:

class Fruit {
	// 水果
}
class Apple extends Fruit {
	// 苹果
}
class RedApple extends Apple {
	// 红苹果
}
class Pear extends Fruit {
	// 梨
}

// 生产者
class Producer<E> {
	public void produce(List<? extends E> list) {
		// ...生产(写),看下限add,所以用extends来接收一个下限类型
	}
}
main {
	Producer<Fruit> p = new Producer<>();
	List<Apple> apples = new ArrayList<>();
	p.produce(apples);  
		// ==> List<? extends Fruit> list = new ArrayList<Apple>();
}

// 消费者
class Consumer<E> {
	public E consume(List<? super E> list) {
		// ...消费(读),看上限get,所以用super来接收一个上限类型
		E e = (E) list.get(0);
		return e;
	}
}
main {
    Consumer<RedApple> c = new Consumer<>();
    List<RedApple> redApples = new ArrayList<>();
    c.consume(redApples);   
    	// ==> List<? super RedApple> list = new ArrayList<RedApple>();
    List<Apple> apples = new ArrayList<>();
    c.consume(apples);      
    	// ==> List<? super RedApple> list = new ArrayList<Apple>();
}

猜你喜欢

转载自blog.csdn.net/sun8112133/article/details/89133616