通配符
> 不能添加
extends Object> 不能添加
super FujiApple> 不能添加父对象
实参类型List extends Apple>,形参类型List extends Fruit> ,方法内外泛型范围大小不一致
实参不能添加list.add(new Fruit()),形参可以添加list.add(new Fruit()),产生了二义性
实参类型List super Apple>,形参类型List super ShangDongApple>
实参能添加本类对象list.add(new Apple()),实参能添加子类对象list.add(new ShangDongApple()),形参能添加本类对象list.add(new ShangDongApple()),形参能添加子类对象list.add(new YanTaiApple())
package com.xcrj.unified;
import java.io.Serializable;
/**
* 泛型
* 编译期,进行泛型擦除和泛型检查
* 编译期,能够确定泛型具体类型才可以使用(直接给泛型声明赋值;传入具体类型间接赋值泛型声明)
*/
// xcrj 对象泛型声明 对属于对象属性和方法生效
public class Result<T> implements Serializable{
private static final long serialVersionUID = 1L;
//是否成功
private Boolean succuss;
//错误码
private String code;
//消息提示
private String description;
//结果对象
private T data;
//服务器当前时间戳
private Long millis = System.currentTimeMillis();
/**
* 构造器私有化
*/
private Result() {}
/**
* 构造器私有化
*/
private Result(Boolean succuss, String code, String description, T data) {
this.succuss = succuss;
this.code = code;
this.description = description;
this.data = data;
}
//1. 成功只有无返回值,有返回值两种情况
//2. 成功只有SUCCESS枚举,没有其他ErrorCode枚举
public static <T> Result<T> success() {
return new Result<T>(true,ErrorCode.SUCCESS.getCode(),ErrorCode.SUCCESS.getDescription(),null);
}
// xcrj 静态方法 泛型声明
// 泛型声明;Result返回类型,没有指明泛型时仍然需要写T
public static <T> Result<T> success(T data) {
// new Result创建对象
return new Result<T>(true,ErrorCode.SUCCESS.getCode(),ErrorCode.SUCCESS.getDescription(),data);
}
//1. 错误必须指定Errorcode,若无法确定具体错误,选择宏观错误
//2. 错误只允许返回Errorcode,不允许返回数据data
public static <T> Result<T> error(ErrorCode errorCode) {
return new Result<T>(false,errorCode.getCode(),errorCode.getDescription(),null);
}
// spring mvc在序列化时需要用到setter和getter
public Boolean getSuccuss() {
return succuss;
}
public void setSuccuss(Boolean succuss) {
this.succuss = succuss;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public Long getMillis() {
return millis;
}
public void setMillis(Long millis) {
this.millis = millis;
}
}
泛型不能使用在静态属性上?
答:不可以,编译期间无法确定静态属性泛型的具体类型
泛型可以使用在静态方法上?
答:可以,在static关键字后面 声明泛型即可
//方式1,编译报错
public static T demo2(T t) {
return t;
}
//方式2,可用,因为拥有泛型声明
public static <W> void demo3(W w) {
System.out.println(w);
}
泛型不能使用在基本类型上?
答:编译期间泛型擦除后都会变成Object
package com.xcrj.java1;
// 泛型成员属性,需要在类名后面声明泛型
public class Test1<T>{
private T name;
public Test1(T name){
this.name=name;
}
public static void main(String[] args) {
Test1<String> test1=new Test1<>("xcrj");
System.out.println(test1.name);
}
}
package com.xcrj.java1;
// 泛型成员方法,在方法返回类型前声明泛型
public class Test2 {
// xcrj 在返回类型后面声明泛型作用于入参类型
public <T> void test(T name){
System.out.println(name);
}
public static void main(String[] args) {
Test2 test2=new Test2();
// 显示指明泛型类型
test2.<String>test("xcrj");
}
}
package com.xcrj.java1;
// 泛型静态方法,在方法返回类型前声明泛型
public class Test3 {
// xcrj 在返回类型后面声明泛型作用于入参类型
public static <T> void test(T name){
System.out.println(name);
}
public static void main(String[] args) {
// 显示指明泛型类型
Test3.<String>test("xcrj");
}
}
package com.xcrj.java1;
// 泛型构造方法,在方法返回类型前声明泛型
public class Test4 {
// xcrj 在返回类型后面声明泛型作用于入参类型
public <T> Test4(T name){
System.out.println(name instanceof String);
System.out.println(name);
}
public static void main(String[] args) {
// 显示指明泛型类型
new <String>Test4("xcrj");
}
}
package com.xcrj.java1;
// 泛型类,T-type, K-Key, V-value, E-element
public class Test5<T,K,V,E> {
public void test(T namet,K namek,V namev,E namee){
System.out.println(namet);
System.out.println(namek);
System.out.println(namev);
System.out.println(namee);
}
public static void main(String[] args) {
Test5<String,String,String,String> test5=new Test5<>();
test5.test("xcrjt","xcrjk","xcrjv","xcrje");
}
}
package com.xcrj.java1;
// 泛型接口
public interface Test6<T,K,V,E> {
// java8增强接口,default void方法
default String test(T namet,K namek,V namev,E namee){
System.out.println(namet);
System.out.println(namek);
System.out.println(namev);
System.out.println(namee);
return "";
}
// java8增强接口,default void方法
public static void main(String[] args) {
// 使用接口创建 匿名类对象
Test6<String,String,String,String> test6=new Test6<String,String,String,String>() {};
test6.test("xcrjt","xcrjk","xcrjv","xcrje");
}
}
package com.xcrj.java1;
/**
* 泛型类继承,指明父类的泛型,减少了父类的泛型,子类中仍然需要写未指明的泛型,当然也可以增加新的泛型
* 指明父类泛型T, K为String
* 继承父类泛型V, E
* 声明更多泛型A, B
*/
public class Test5Son1<V,E,A,B> extends Test5<String,String,V,E> {
public void test(String nametson,String namekson,V namevson,E nameeson,A nameason,B namebson){
System.out.println(nametson);
System.out.println(namekson);
System.out.println(namevson);
System.out.println(nameeson);
System.out.println(nameason);
System.out.println(namebson);
}
public static void main(String[] args) {
Test5Son1<String,String,String,String> test5Son1=new Test5Son1<String,String,String,String>();
test5Son1.test("xcrjString","xcrjString","xcrjvson","xcrjeson","xcrjason","xcrjbson");
}
}
package com.xcrj.java1;
/**
* 泛型实现:指明接口的泛型,减少了接口的泛型,实现类中仍然需要写未指明的泛型,当然也可以增加新的泛型
* 指明接口泛型T, K为String
* 实现父类泛型V, E
* 声明更多泛型A, B
*/
public class Test6Impl1<V,E,A,B> implements Test6<String,String,V,E> {
@Override
public String test(String nametImpl, String namekImpl, V namevImpl, E nameeImpl) {
System.out.println(nametImpl);
System.out.println(namekImpl);
System.out.println(namevImpl);
System.out.println(nameeImpl);
return "";
}
public String test1(String nametImpl, String namekImpl, V namevImpl, E nameeImpl, A nameaImpl, B namebImpl) {
System.out.println(nametImpl);
System.out.println(namekImpl);
System.out.println(namevImpl);
System.out.println(nameeImpl);
System.out.println(nameaImpl);
System.out.println(namebImpl);
return "";
}
public static void main(String[] args) {
Test6Impl1<String,String,String,String> test6Impl1=new Test6Impl1<>();
test6Impl1.test("xcrjString", "xcrjString", "xcrjvImpl", "xcrjeImpl");
test6Impl1.test1("xcrjString", "xcrjString", "xcrjvImpl", "xcrjeImpl", "xcrjaImpl", "xcrjbImpl");
}
}
package com.xcrj.java1;
import java.util.List;
import java.util.ArrayList;
/**
* 泛型擦除,在使用时,继承时,实现时没有指定泛型的具体的类型,以Object进行处理
* 编译时,进行泛型擦除,按Object处理
* 编译时,进行泛型检查
* 运行时,泛型都被替换为Object了,类信息仍在
*/
public class Test7 {
public static void main(String[] args) {
// 在使用时没有指定泛型的具体的类型,以Object进行处理
List list=new ArrayList<String>();
list.add("String");
list.add(1);
list.add(true);
System.out.println("===================");
for(Object obj:list){
System.out.println(obj.getClass().getName());
System.out.println(obj);
}
// 在使用时指定泛型的具体的类型,进行泛型检查
List<String> list1=new ArrayList<String>();
list1.add("String");
// 泛型检查不通过
// list1.add(1);
// list1.add(true);
}
}
package com.xcrj.java1;
import java.util.List;
import java.util.ArrayList;
/**
* 通配符
* > 不能添加
* extends Object> 不能添加
* super ShangDongApple> 不能添加父对象
* 实参类型List extends Apple>,形参类型List extends Fruit>
* 实参不能添加list.add(new Fruit()),形参可以添加list.add(new Fruit()),产生了二义性,因此extends不允许添加
* 实参类型List super Apple>,形参类型List super ShangDongApple>
* 实参能添加本类对象list.add(new Apple()),实参能添加子类对象list.add(new ShangDongApple()),形参能添加本类对象list.add(new ShangDongApple()),形参能添加子类对象list.add(new YanTaiApple())
*/
public class Test8 {
public static void main(String[] args) {
// 不能添加
List<?> list=new ArrayList<>();
// list.add("Str");
// 不能添加
List<? extends Apple> list1=new ArrayList<>();
// list1.add(new Fruit());
// list1.add(new Apple());
// list1.add(new ShangDongApple());
testExtends(list1);
// 传入更大范围
testExtends1(list1);
// 不能添加父对象
List<? super Apple> list2=new ArrayList<>();
// 可以添加本对象
list2.add(new Apple());
// 可以添加子对象
list2.add(new ShangDongApple());
// 不能添加父对象
// list2.add(new Apple());
testSuper(list2);
// 传入更大范围
testSuper1(list2);
}
public static void testExtends(List<? extends Apple> list){
}
// 实参类型List extends Apple>,形参类型List extends Fruit>
// 实参不能添加list.add(new Fruit()),形参可以添加list.add(new Fruit()),产生了二义性,因此extends不允许添加
public static void testExtends1(List<? extends Fruit> list){
// list.add(new Fruit());
}
public static void testSuper(List<? super Apple> list){
}
// 实参类型List super Apple>,形参类型List super ShangDongApple>
// 实参能添加本类对象list.add(new Apple()),实参能添加子类对象list.add(new ShangDongApple()),形参能添加本类对象list.add(new ShangDongApple()),形参能添加子类对象list.add(new YanTaiApple())
public static void testSuper1(List<? super ShangDongApple> list){
list.add(new ShangDongApple());
list.add(new YanTaiApple());
}
}
package com.xcrj.java1;
public class Fruit {
}
package com.xcrj.java1;
public class Apple extends Fruit{
}
package com.xcrj.java1;
public class ShangDongApple extends Apple{
}
package com.xcrj.java1;
public class YanTaiApple extends ShangDongApple {
}