首页 > 学院 > 开发设计 > 正文

泛型分析

2019-11-06 06:28:02
字体:
来源:转载
供稿:网友

1、泛型入门

一、我们把一个对象丢进集合里面,但是集合就会把该对象的类型忘记,取出这个集合的对象时就变成了object类型,泛型可以让我们集合存储特定的类型

看代码

package test01;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/* * 使用泛型 */public class Ftest1 { public static void main(String[] args) { List list = new ArrayList(); list.add("woshishui"); list.add(1234); list.add("ef"); System.out.PRintln(list.get(1)); //int in1 = list.get(1); 不行要通过强制转化,因为丢进去就成了Object类 int in = (int)list.get(1); //使用泛型 List<String> list2 = new ArrayList<String>();//只容许存放String类 //list2.add(Integer(1234)); 报错,传入不是String类 list2.add("1234"); System.out.println(list2.get(0)); //java7.0以后的泛型语法 List<String> list3 = new ArrayList<>(); //只能装入一个String类和List类的对象,list类对象只能装入String类 Map<String,List<String>> map1 = new HashMap<>(); List<String> strstring = new ArrayList<>(); strstring.add("第一个"); strstring.add("wwwww"); strstring.add("第二个"); strstring.add("QQqqq"); map1.put("n.1key", strstring); System.out.println(map1.get("n.1key")); for(String key:map1.keySet()) { //用一个循环输出map List<String> lis = map1.get(key); System.out.println(key + "-->" +lis + " , "); } }}

二、有关泛型类和泛型类继承:

看代码与注释:

package 有关带有泛型的继承;/* * 父类定义的泛型如果在子类时没有确定泛型的类型,那么子类必须继承过来,子类可以自己增加泛型 * 父类定义的泛型如果在子类实现那么,子类可自己定义或不定义泛型 * */class Apple<T> { T info; public Apple(){ System.out.println("没有任何参数的Apple构造函数"); } public Apple(T info) { this.info = info; System.out.println("带有泛型参数的构造函数"); } public Apple(String info){ //this.info = info; 不行,不知道属性info是什么类型 System.out.println("普通带参的构造函数"); }}class B<T> extends Apple<T> { //父类没有指定泛型是什么类型,子类必须继承 public B(T info,String str) { //super(str); //子类的构造器通过调用super 来调用父类的构造器代码 //super(info); 不能多次调用构造器,原因是,super 只能写在该代码段第一行 }}class C<TT> extends Apple<String> {// 父类泛型类型确定子类可以自定义泛型或者不定义泛型 public C(String info){ //super(info);这行代码不确定 调用的是哪个构造函数 }}public class test01 { public static void main(String[] args) { B b = new B(333,"rrr"); //C c = new C("ddd"); }}

泛型通配符:

package 通配符;import java.util.ArrayList;import java.util.List;/* * 1、通配符定义的泛型类型 list<?>, 表示list<?>是各种泛型list的父类,但是并不能把元素加入其中 * 2、但是不能在通配符定义的泛型类型里丢入对象,因为不知道<?>是什么类型空值可以被丢 * 3、在list<?>中取出对象时,默认是object类的对象,所以若要取出指定类型的对象就要强制转化 * 4、通配符上限就是将传进集合的对象继承一个父类,List<? extends Shape>,这样子当我们集合里面的对象拿出来时就不用强制转化 * 5、在给泛型设置通配符上限的时候,我们传的是一个设有上限的未知子类,所以不能向集合里面抛对象 * */public class test01 { public static void test(List<?> list){ for(int i=0;i<list.size();i++) { //list.add(111); 报错 :The method add(int, capture#2-of ?) in the type List<capture#2-of ?> is not applicable for the arguments (int) //list.add(null);//空值可以 System.out.println(list.get(i)); Integer in = (Integer)list.get(i); //被默认总是object要强制转化 System.out.println(" in is :" + in); } } public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(123); list.add(234); list.add(345); test01.test(list); }}

通配符下限

package 通配符下限;import java.util.ArrayList;import java.util.Collection;import java.util.List;/* * */public class Test { public static <T> T copy2(Collection<? extends T> dest,Collection<T> src){ T last = null; for(T t:dest) { last = t; src.add(t); } return last; } /* * 最后一个形参传入泛型 T=Integer ,所以第一个形参?super T ,?=Number */ public static <T> T copy3(Collection<? super T> from,Collection<T> to) { T test = null; for(T t:to) { from.add(t); } return test; } public static void main(String[] args) { List<Number> number = new ArrayList<>(); List<Integer> integer = new ArrayList<>(); //copy(number,integer); copy2(integer,number); copy3(number,integer); }}

菱形语法与泛型构造器:

package 菱形语法泛型构造器;/*知识点1、在调用构造器时可以让编译器根据形参的值来推断形参的类型 *知识点2、可显式的让用户输入形参类型 如:Myclass<Integer> ms3 = new <Double>Myclass<Integer>(6.3); * */ class Myclass<E> { public Myclass(Integer t) { //一号构造 System.out.println(t); } public<T> Myclass( T t) { //二号构造 System.out.println(t); }}public class TestFoo01 { public static void main(String[] args) { // Myclass<Integer> ms = new Myclass<>(99); //调用一号构造 Myclass<Integer> ms2 = new Myclass<>("sss"); //调用二号构造 /* * Myclass 中E的形参类型是Integer,如果显示指定构造器中T形参类型,那么菱形语法必须要传入E形参类型 */ Myclass<Integer> ms3 = new <Double>Myclass<Integer>(6.3); }}

泛型方法:

package 泛型方法;/*知识点1、泛型方法主要是解决泛型形参的问题类似于形参 list<Collection>不是list<String>的父类 *知识点2、类型方法中定义的类型只能在该方法中有效 *知识点3、调用泛型方法和普通方法一样 *知识点4、向泛型方法中传入参数时,不要让系统不知道指定的是哪一个类型, * 一个方法的返回值类型依赖于另一个形参类型,那么使用泛型方法更好一点 */import java.util.ArrayList;import java.util.Collection;import java.util.List;public class Test01 { // *知识点2、类型方法中定义的类型只能在该方法中有效 public static <T> void test(Collection<T> from,Collection<T> to){ for(T c:from) { to.add(c); } } public static <T> void test2(List<? extends T> from,List<T> to){ for(T c:from) { to.add(c); } } public static void main(String[] args) { List<String> list = new ArrayList<>(); List<String> list2 = new ArrayList<>(); test(list,list2); // *知识点3、调用泛型方法和普通方法一样 //test(list,list2); List<Collection> list3 = new ArrayList<>(); List<String> list4 = new ArrayList<>(); //test01(list3,list4); 知识点4 系统识别出T的类型到底是什么 //test2(list4,list3); }}

擦除、转换

package 擦除与转换;/* * 当一个具有泛型信息的对象赋值给另一个没有泛型信息的变量时,菱形语法擦除,比如List<String> 转化成List,该 * List对集合元素的类型检查变成类型变量的上限,再比如 List<T extends Number> 转化成 List,则该List的对象 * 是上限 Number */class Apple<T extends Number> { T size; public Apple() { } public Apple(T size) { this.size = size; } public void getsize(T size) { this.size = size; } public T setsize() { return this.size; }}public class Test { public static void main(String[] args) { Apple<Integer> a = new Apple<>(123); Integer b = a.setsize(); //把菱形语法去除 没有出现警告,擦除 Apple c = a; //赋值后 c 只知道 size 是Number 类型的 //Integer integer = c.setsize(); Number integer = c.setsize(); }}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表