文章目录
1、泛型
Generics 是指在定义类的时候不指定类中某个信息(属性/方法返回值)的具体数据类型,而是用一个标识符来替代,当外部实例化对象的时候再来指定具体的数据类型。
集合和数组相比较,优势在于长度可以随时改变,集合中存储的数据类型是灵活的,不固定。
1.1、为什么要使用泛型?
使用泛型可以确保集合中数据的统一性,同时它又兼具很好的灵活性
java
package com.htl.test;
import java.util.ArrayList;
public class Test3 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList();
list.add(1);
list.add(2);
for (int i = 0; i < list.size(); i++) {
int num = list.get(i);
System.out.println(num);
}
}
}
1.2、泛型的应用
在自定义类中添加泛型,基本语法
java
public class 类名<泛型标识1,泛型标识2...>{
private 泛型标识1 id;
public 泛型标识2 test(){
return (泛型标识2) new Object();
}
}
自定义一个表示时间的类 Time
java
package com.htl.test;
public class Time<T> {
private T value;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
}
java
package com.htl.test;
public class Test4 {
public static void main(String[] args) {
Time<Integer> time1 = new Time<>();
time1.setValue(10);
System.out.println("现在的时间是" + time1.getValue());
Time<String> time2 = new Time<>();
time2.setValue("十点");
System.out.println("现在的时间是" + time2.getValue());
}
}
java
package com.htl.test;
public class Test5 {
public static void main(String[] args) {
Time2<String,Integer,Float> time = new Time2<>();
time.setHour("十点");
time.setMinute(10);
time.setSeconde(10.0f);
System.out.println("现在的时间是" + time.getHour() + ":" + time.getMinute() + ":" + time.getSeconde());
}
}
java
package com.htl.test;
public class Time2<H,M,S> {
private H hour;
private M minute;
private S seconde;
public H getHour() {
return hour;
}
public void setHour(H hour) {
this.hour = hour;
}
public M getMinute() {
return minute;
}
public void setMinute(M minute) {
this.minute = minute;
}
public S getSeconde() {
return seconde;
}
public void setSeconde(S seconde) {
this.seconde = seconde;
}
}
静态成员不能用泛型来修饰,非静态成员变量可以用泛型。
静态成员变量在类加载的时候就存入到内存中了,没有类型,所以无法存入,就不能定义为静态的。
静态方法可以使用泛型
java
private static Object hour;
public static<H> H getHour() {
return (H)hour;
}
1.3、泛型通配符
String 和 Integer 在泛型引用中不能转换为 Object,多态在泛型引用中不生效
java
package com.htl.test2;
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
ArrayList<String> list1 = new ArrayList<>();
test(list1);
ArrayList<Integer> list2 = new ArrayList<>();
test(list2);
}
/**
* 既可以传入String类型的集合
* 也可以传入Integer类型的集合
*/
public static void test(ArrayList<?> list){
}
}
1.4、泛型上限和下限
使用泛型的时候可以通过泛型上限和下限对数据类型的范围进行扩充
泛型上限
表示实例化时的具体数据类型,可以是上限类型的子类或者上限类型本身,用 extends 关键字来修饰。
泛型下限
表示实例化时的具体数据类型,可以是下限类型的父类或者下限类型本身,用 super 关键字来修饰。
基本语法:
java
泛型上限:类名<泛型标识符 extends 上限类名>
泛型下限:类名<泛型标识符 super 下限类名>
java
package com.htl.test2;
public class Time<T> {
public static void main(String[] args) {
test(new Time<Number>());
test(new Time<Byte>());
test(new Time<Integer>());
test2(new Time<String>());
test2(new Time<Object>());
}
/**
* 参数的泛型只能是Number或者它的子类,Number、Byte、short、Integer...
*/
public static void test(Time<? extends Number> time){
}
/**
* 参数的泛型只能是String或者它的父类,String和Object
*/
public static void test2(Time<? super String> time){
}
}
1.5、泛型接口
我们在定义类的时候可以使用泛型,定义接口的时候同样可以使用泛型。
java
public interface MyInterface<T>{
public T getValue();
}
实现泛型接口有两种方式,一种是实现类在定义时继续使用泛型标识,另一种时实现类在定义时直接给出具体的数据类型。
1、实现类继续使用泛型
java
package com.htl.test3;
public class MyImplement<T> implements MyInterface<T> {
private T obj;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
@Override
public T getValue() {
return null;
}
}
2、实现类给出具体的数据类型
java
package com.htl.test3;
public class MyImplement2 implements MyInterface<String> {
private String obj;
public String getObj() {
return obj;
}
public void setObj(String obj) {
this.obj = obj;
}
@Override
public String getValue() {
return null;
}
}
实现类继续使用泛型,在具体实例化的时候需要给出具体的数据类型。
实现类给出具体的数据类型,在具体实例化的时候不需要给出具体的数据类型。
java
package com.htl.test3;
public class Test {
public static void main(String[] args) {
MyImplement<String> myInterface = new MyImplement<>();
MyImplement2 myInterface1 = new MyImplement2();
}
}
2、枚举
Enum 是一种有确定取值区间的数据类型,本质上就是一个类,简洁、安全、方便。
枚举的值被约束到一个特定的范围,只能从这个范围内取值。
java
package com.htl.test3;
public enum WeekEnum {
MONDAY,TUESDAY,WEDENSDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY;
}
java
package com.htl.test3;
public enum ResponseEnum {
SUCCESS(0,"成功"),
ERROR(-1,"失败");
private Integer code;
private String msg;
public Integer getCode() {
return code;
}
public String getMsg() {
return msg;
}
ResponseEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
}
java
package com.htl.test3;
public class Test2 {
public static void main(String[] args) {
System.out.println(ResponseEnum.SUCCESS.getCode());
System.out.println(ResponseEnum.ERROR.getMsg());
}
}