java 泛型操作
1 接口
package com.example.astest.demo.gener; // //接口的泛型是最容易定义和实现的,子类可以随意定义其类型及重写其方法 9成的泛型在接口 //泛型的直接用途是强转 和 判断类型 instanceof public interface Generator<R> { public R next(); }
2 实现类一
package com.example.astest.demo.gener; /** * @Auth * @classname GeneratorImpl * @Description //TODO * @Date 2:06 PM 24/07/2020 * version 1.0 **/ //如果实现的子类没有带泛型会报错 反省写别的也会报错 public class GeneratorImpl<T> implements Generator<T> { @Override public T next() { return null; } }
3实现类二
package com.example.astest.demo; import com.example.astest.demo.gener.Generator; import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; import java.util.List; import java.util.Random; /** * @Aut * @classname Generic * @Description //TODO * @Date 5:09 PM 21/07/2020 * version 1.0 **/ @Data @Slf4j public class Generic<E> implements Generator<String> { // 子类的数组可以直接给父类数组赋值 同样适用于泛型 所有类继承于Object ArrayList[] a={}; List[] numbers=a; // ArrayList public boolean add(E e) { // ensureCapacityInternal(size + 1); // Increments modCount!! // elementData[size++] = e; 这里的elementData 是个Object数组 // return true; // } private E taget; public Generic(E taget) { this.taget = taget; } public Generic() { } public E getTaget(){ return taget; } //此处的?和Number、String、Integer一样都是一种实际的类型,可以把?看成所有类型的父类。是一种真实的类型。 //但是通配符代表的是某个字母泛型 而不能单独作为一种泛型 例如用Generic<?>代替Generic<E> 或者付给一个 //真实的类型如 Generator<String> public void showKeyValue1(Generic<?> obj){ log.debug("泛型测试","key value is " + obj.getTaget()); // obj.setTaget(45); 这个语法是错误的,因为<?>代表不了任何类型 // obj.setTaget(taget); 错误 虽然target是E类型但也不是<?> } public Generic<E> returnMethod(E a){ return new Generic<E>(a); } //这里不能改变返回类型 还有泛型改字母不算重载 public ArrayList<E> returnMethod(){ return new ArrayList<E>(); } // 返回值的泛型已经改变 public static <T> Generic<T> returnMethodTwo(){ return new Generic<>(); } public <T> T printMsg( T... args){ for(T t : args){ log.debug("泛型测试","t is " + t); } return args[0]; } public static <T> T printMsgStatic( T... args){ for(T t : args){ log.debug("泛型测试","t is " + t); } return args[0]; } @Override public String next() { Random rand = new Random(); return rand.ints().toString(); } public <T> T genericMethod(Class<T> tClass ) throws IllegalAccessException, InstantiationException { // T inst = (T) ca.newInstance(initargs); return tClass.newInstance(); } public static <T> T genericMethods(Class<T> tClass ) throws IllegalAccessException, InstantiationException { // T inst = (T) ca.newInstance(initargs); return tClass.newInstance(); } }
4 测试类
package com.example.astest.demo; import com.example.astest.demo.poiwrite.GetPaidProService; import lombok.extern.slf4j.Slf4j; import mockit.Expectations; import mockit.Tested; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.Test; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.DoubleAdder; /** * @Auth * @classname GenericTest * @Description //TODO * @Date 5:08 PM 21/07/2020 * version 1.0 **/ @Slf4j public class GenericTest { @Test void setvalue1() throws ClassNotFoundException, InstantiationException, IllegalAccessException { //通配符作用一 可以放入不同实例 未指定的通配符相当于object Generic generic=new Generic("sds"); log.debug(generic.getTaget().toString()); assertEquals("sds",generic.getTaget()); generic.setTaget(false); assertEquals(false,generic.getTaget()); //下面的语句是错误的,因为一开始没指定类型所以现在是Object //Boolean a=generic.getTaget(); log.debug(generic.getTaget().toString()); Object slf4j= generic.genericMethod(Class.forName("com.example.astest.demo.poiwrite.GetPaidProService")); Generic generic2= new Generic<>(12); Object slfaa4j= generic2.genericMethod(new ClassLoader() { @Override public Class<?> loadClass(String name) throws ClassNotFoundException { return super.loadClass(name); } }.loadClass("java.lang.String")); //参数被事先声明过不能乱加 generic2.showKeyValue1(generic); Object slf4js= generic.genericMethods(Class.forName("com.example.astest.demo.poiwrite.GetPaidProService")); assertNotNull(slf4j); } //返回实例测试 void returntest(){ // SysUser sysUser = sysUserService.get One(Wrappers.<SysUser>query().lambda().eq(SysUser::getUsername,username)); // public static <T> QueryWrapper<T> query() { // return new QueryWrapper<>(); // } // public <T> ArrayList<T> returnMethodTwo(){ // return new ArrayList<>(); // } //public class QueryWrapper<T> extends AbstractWrapper<T, String, QueryWrapper<T>> // implements Query<QueryWrapper<T>, T, String> { Generic generic=new Generic("sds"); // Generic<Integer> genericc= generic.<String>returnMethodTwo(); error Generic<String> genericc= generic.<String>returnMethodTwo(); Generic<Integer> genericcc= generic.<Integer>returnMethodTwo(); List<String> genericc2= generic.<Integer>returnMethod(); //no error ArrayList<String> genericc3= generic.<Integer>returnMethod(); //no error Object a= generic.<String>printMsg("1","2"); //error 不加静态就是object String string= generic.printMsgStatic("1","2"); //加了静态就能变 } //问号通配符实战 void test2(){ //通配符作用1 ArrayList<String> arrayList1=new ArrayList<>(); String a= arrayList1.get(0); ArrayList<Integer> arrayList2=new ArrayList<>(); //问号作用 arrayList1.removeAll(arrayList2); // public boolean removeAll(Collection<?> c) { // Objects.requireNonNull(c); // return batchRemove(c, false); // } } //问号通配符实战2 void supertest(){ List<? super Number> list = new ArrayList<Number>(); // OK 找父类或同类 List<? super Number> list2 = new ArrayList<Object>(); // OK List<? extends Number> listw = new ArrayList<DoubleAdder>(); //找子类 或同类 } //泛型数组 void arraylistlist(){ List<?>[] ls = new ArrayList<?>[10]; List<String>[] lss = new ArrayList[10]; // List<String>[] lsa = new List<String>[10]; // Not really allowed. 不允许 List<String>[] lsa = new List[10]; Object o = lsa; Object[] oa = (Object[]) o; List<Integer> li = new ArrayList<Integer>(); li.add(new Integer(3)); oa[1] = li; // Unsound, but passes run time store check String s = lsa[1].get(0); // Run-time error: ClassCastException. } }