第22 章 : 泛型
96 泛型問題引出
JDK >= 1.5
主要為了解決 ClassCastException
舉例:
要描述一個坐标類,允許存放以下坐标資料類型
整型 x = 10, y = 20
浮點型 x = 10.1, y = 20.2
字元串型 x = 東經 10 度 , y = 北緯 20 度
可以使用Object,不過會出現轉型操作
整型: 基本資料類型 -> Integer包裝類 -> 自動向上轉型為Object
浮點型 :基本資料類型 -> Double包裝類 -> 自動向上轉轉型為Object
字元串型 :String對象 -> 自動向上轉轉型為Object
class Point{
private Object x ;
private Object y ;
public Point(Object x, Object y){
this.x = x ;
this.y = y ;
}
public void setX(Object x){
this.x = x ;
}
public void setY(Object y){
this.y = y ;
}
public Object getX(){
return this.x ;
}
public Object getY(){
return this.y ;
}
@Override
public String toString(){
return "Point("+ this.x + ", " + this.y + ")" ;
}
}
class Demo{
public static void main(String[] args) {
Point p1 = new Point(1, 2);
System.out.println(p1); // Point(1, 2)
int x = (Integer)p1.getX() ;
System.out.println(x); // 1
Point p2 = new Point(1.1, 2.2);
System.out.println(p2); // Point(1.1, 2.2)
// Object 不能限制傳入的參數
Point p3 = new Point(10, "北緯20度");
System.out.println(p3); // Point(10, 北緯20度)
}
}
97 泛型基本定義
類中屬性或方法的參數與傳回值類型由對象執行個體化的時候動态決定
需要在類定義的時候明确的定義占位符(泛型标記)
執行個體化不設定泛型類型,預設使用Object
Point<Integer> p1 = new Point<Integer>(1, 2);
泛型的好處:
1、編譯時檢查類型,避免出現安全隐患
2、避免向下轉型操作
泛型注意點:
1、隻能使用引用類型,基本類型要使用包裝類
2、JDK >=1.7開始可以簡寫
Point<Integer> p1 = new Point<>(1, 2);
使用泛型可以解決大部分的類對象強制轉換處理
class Point<T>{
private T x ;
private T y ;
public Point(){}
public Point(T x, T y){
this.x = x ;
this.y = y ;
}
public void setX(T x){
this.x = x ;
}
public void setY(T y){
this.y = y ;
}
public T getX(){
return this.x ;
}
public T getY(){
return this.y ;
}
@Override
public String toString(){
return "Point("+ this.x + ", " + this.y + ")" ;
}
}
class Demo{
public static void main(String[] args) {
Point<Integer> p1 = new Point<Integer>(1, 2);
System.out.println(p1); // Point(1, 2)
int x = (Integer)p1.getX() ;
System.out.println(x); // 1
Point<Double> p2 = new Point<Double>(1.1, 2.2);
System.out.println(p2); // Point(1.1, 2.2)
Point<String> p3 = new Point<String>("東經30度", "北緯20度");
System.out.println(p3); // Point(10, 北緯20度)
}
}
98 泛型通配符
目前的泛型進行引用傳遞
class Message<T>{
private T content;
public void setContent(T message){
this.content = message;
}
public T getContent(){
return this.content;
}
}
class Demo{
public static void main(String[] args) {
Message<String> message = new Message<>();
message.setContent("Hello Java");
showMessage(message);
}
// 隻能接收Message<String> 對象
public static void showMessage(Message<String> message){
System.out.println(message.getContent());
// Hello Java
}
}
修改為通配符接收資料
public static void showMessage(Message<?> message) {
System.out.println(message.getContent());
// Hello Java
}
設定泛型範圍
// 設定泛型上限
// ? extends 類
// 例如:隻允許設定Number 或其子類
? extends Number
// 設定泛型下限
// ? super 類
// 例如:隻能夠使用String 或其父類
? super String
public static void showMessage(Message<? extends Number> message) {
System.out.println(message.getContent());
}
public static void showMessage(Message<? super String> message) {
System.out.println(message.getContent());
}
99 泛型接口
1、實作類繼續使用泛型
interface IMessage<T>{
public void echo(T t);
}
class Messageimpl<S> implements IMessage<S> {
public void echo(S t){
System.out.println(t);
}
}
class Demo{
public static void main(String[] args) {
Messageimpl<String> message = new Messageimpl<>();
message.echo("Hello");
// Hello
}
}
2、實作類不使用泛型
interface IMessage<T>{
public void echo(T t);
}
class Messageimpl implements IMessage<String> {
public void echo(String t){
System.out.println(t);
}
}
class Demo{
public static void main(String[] args) {
Messageimpl message = new Messageimpl();
message.echo("Hello");
// Hello
}
}
100 泛型方法
泛型方法:泛型标記寫到了方法上
泛型方法不一定非要出現在泛型類中
class Demo{
public static <T> T[] getArray(T ...args){
return args;
}
public static void main(String[] args) {
Integer[] list = getArray(1, 2, 3);
for(int x : list){
System.out.println(x);
// 1 2 3
}
}
}