Java在JDK5中添加了增強for,靜态導入,可變參數,泛型,自動拆裝箱等新特性。
自動拆裝箱在基本類型的包裝類型的文章中總結過。這裡主要說增強for,靜态導入、可變參數和泛型。
增強for循環
增強for的出現主要是為了替代疊代器,使代碼更加簡潔。
增強for的缺點:
如果集合為空則會發生異常。需要加非空判斷。
增強for依然會發生并發修改異常,需要周遊修改的時候還是要使用普通for,size和get方法相結合來周遊。
import java.util.ArrayList;
public class test {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("hello");
list.add("world");
list.add("java");
// 增強for
if (list != null) {
// 非空判斷防止發生空指針異常NullPointerException
for (String s : list) {
System.out.print(s + ",");// hello,world,java,
}
}
}
}
靜态導入
靜态導入的格式:
import static 包名.類名.方法名
靜态導入後可以直接通過方法名來使用方法。前提是該方法本身是靜态的。
//靜态導入
import static java.lang.Math.abs;
import static java.lang.Math.max;
import static java.lang.Math.min;
public class test {
public static void main(String[] args) {
int a = 5;
int b = -1;
// 靜态導入後可以直接使用該方法
System.out.println(abs(b));// 1
System.out.println(max(a, b));// 5
System.out.println(min(a, b));// -1
}
}
可變參數
當方法的參數個數不确定的時候可以使用可變參數,在源碼裡面出現的多,實際開發慎用。
public class test {
public static int sum(int... a) {// 定義可變參數
// 可變參數相當于數組的處理方式
// 定義最終結果變量
int result = 0;
// 通過增強for周遊處理a
for (int i : a) {
result += i;
}
return result;
}
public static void main(String[] args) {
int a = 1;
int b = 2;
int c = 3;
int d = 4;
System.out.println(sum(a, b));// 3
System.out.println(sum(a, b, c));// 6
System.out.println(sum(10, 20, 30));// 60
}
}
泛型
雖然集合可以存儲不同類型的元素,但是當我們周遊集合的時候用來接收的元素類型是固定的,這個時候就容易發生類型不比對的問題,為預防這種問題發生,Java中為我們提供了泛型來限定集合中的元素類型。
加上泛型的好處:
- 解決了黃色警告線的問題。
- 類型不比對問題會在編譯時期就暴露出來,提高了程式的安全性。
- 周遊時不需要強制類型轉化,簡化了代碼,提高可讀性。
import java.util.ArrayList;
import java.util.Iterator;
public class test {
public static void main(String[] args) {
ArrayList<String> a = new ArrayList<String>();
// 在集合的定義中用尖括号裡面寫上元素類型來限定集合的類型
a.add("hello");// 可以解決黃色警告線的問題
a.add("word");
a.add("java");
//a.add(100); 添加類型不比對的元素會在編譯時期就報錯
Iterator<String> it = a.iterator();
while (it.hasNext()) {
String s = it.next();// 不需要強制類型轉化了
System.out.println(s);
}
}
}
/**
hello
word
java
*/
注意:泛型中隻能定義對象類型,也就是說想定義基本類型的時候必須定義成基本類型的包裝類型。
泛型在類上定義
泛型定義在類上可以提高類的安全性,早期定義任意類型的成員變量時使用object表示任意類型,擷取值時需要向下轉型,容易發生類轉換異常ClassCastException
class Student<T> {
//在類上定義泛型
private T obj;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
}
public class test {
public static void main(String[] args) {
// 早期使用object表示任意類型,擷取值時需要向下轉型,容易發生類轉換異常ClassCastException
Student<String> s = new Student<String>();
// 建立對象的時候可以限定對象的類型
s.setObj("張三");
// s.setObj(100);傳入不比對的類型會報錯。
System.out.println("姓名:" + s.getObj());// 姓名:張三
Student<Integer> s2 = new Student<Integer>();
s2.setObj(27);// 這裡自動執行了Integer.valueOf(27)将基本類型裝箱成Integer類型
System.out.println("年齡:" + s2.getObj());// 年齡:27
}
}
同樣,泛型也可以定義在接口上,使用方式和類相似。
泛型在接口上定義
public interface Inter<T> {
// 接口中的變量隻能為常量是以不能用泛型
public static final int num = 100;
public abstract void show(); // 抽象方法
}
class InterImpl<T> implements Inter<T> {
@Override
public void show() {
System.out.println("hello");
}
}
public class InterDemo {
public static void main(String[] args) {
// 第二種情況
Inter<Integer> i2 = new InterImpl<Integer>();
i2.show();//hello
Inter<String> i3 = new InterImpl<String>();
i3.show();//hello
}
}
泛型在方法上定義
class Student{
public <T> void show(T a) {
System.out.println(a);
}
}
public class test {
public static void main(String[] args) {
Student s=new Student();
s.show("張三");
s.show(18);
s.show(true);
}
}
/**
張三
18
true
*/
需要注意,泛型變量不能直接進行運算操作,需要類型轉化。
class Student {
public <T> void show(T a, T b) {
System.out.println((Integer) a + (Integer) b);
}
}
public class test {
public static void main(String[] args) {
Student s = new Student();
s.show(5, 2);//7
}
}
泛型的通配符
<?>
代表任意類型Object類型,或者任意的Java類
<? extends E>
向下限定,E的子類或者E這個類型
<? super E>
向上限定,E及其他的父類
import java.util.ArrayList;
class Person {
}
class Student extends Person {
}
public class InterDemo {
public static void main(String[] args) {
// <?>任意類型
ArrayList<?> a1 = new ArrayList<Person>();
ArrayList<?> a2 = new ArrayList<Student>();
ArrayList<?> a3 = new ArrayList<String>();
// <? extends E> 向下限定
ArrayList<? extends Person> a4 = new ArrayList<Student>();
// ArrayList<? extends Person> a5=new ArrayList<Object>();報錯,隻能為Person本身或它的子類
// <? super E>:向上限定
ArrayList<? super Person> a5 = new ArrayList<Object>();
//ArrayList<? super Person> a6 = new ArrayList<Student>();報錯,隻能為Person本身或它的父類
}
}
集合的嵌套周遊
在泛型中定義一個集合,讓一個大集合包含很多個小集合
import java.util.ArrayList;
class Student {
// 建立一個學生類
private String name;
private int age;
private String specialty;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSpecialty() {
return specialty;
}
public void setSpecialty(String specialty) {
this.specialty = specialty;
}
public Student() {
super();
}
public Student(String name, int age, String specialty) {
super();
this.name = name;
this.age = age;
this.specialty = specialty;
}
}
public class test {
public static void main(String[] args) {
// 每個系有很多個專業每個專業又有很多學生
// 定義一個資訊系大集合
ArrayList<ArrayList<Student>> information = new ArrayList<ArrayList<Student>>();
// 建立計算機班集合
ArrayList<Student> computer = new ArrayList<Student>();
// 建立學生對象
Student c1 = new Student("李四", 21,"計科");
Student c2 = new Student("王五", 22,"計科");
Student c3 = new Student("趙六", 20,"計科");
// 添加學生對象
computer.add(c1);
computer.add(c2);
computer.add(c3);
// 添加到資訊系大集合中
information.add(computer);
// 建立自動化班集合
ArrayList<Student> automation = new ArrayList<Student>();
Student a1 = new Student("劉一", 22,"自動化");
Student a2 = new Student("陳二", 24,"自動化");
Student a3 = new Student("張三", 20,"自動化");
automation.add(a1);
automation.add(a2);
automation.add(a3);
information.add(automation);
// 嵌套周遊
for (ArrayList<Student> arr : information) {
for (Student s : arr) {
System.out.println(s.getName() + "--" + s.getAge()+"--"+s.getSpecialty());
}
}
}
}
/**
李四--21--計科
王五--22--計科
趙六--20--計科
劉一--22--自動化
陳二--24--自動化
張三--20--自動化
*/