精华内容
参与话题
问答
  • 泛型的使用

    2021-01-13 20:20:18
    泛型的使用 泛型的使用有三种,作用在类上的泛型,作用在接口上的泛型和作用在方法上的泛型。 作用在类上的泛型,当实例化以后,类的类型就确定了。 作用在方法上的泛型没有要求 记得编程思想中说过,使用泛型的一个...

    泛型的使用

    泛型的使用有三种,作用在类上的泛型,作用在接口上的泛型和作用在方法上的泛型。
    作用在类上的泛型,当实例化以后,类的类型就确定了。
    作用在方法上的泛型没有要求
    记得编程思想中说过,使用泛型的一个基本指导原则:无论何时,能用泛型方法就不要用泛型类。另外,static方法无法访问泛型类的泛型参数。如果static方法想要使用泛型能力,就必须定一个成一个泛型方法。如上所述,定义一个泛型方法只需要在返回值前面加上泛型参数,和泛型类有所区别的是,泛型类在创建的时候就必须指明泛型参数的值,而泛型方法则不需要,可以使用任意类型调用泛型方法,就好像这是一个被无限次重载过的方法。
    如果想要使用泛型边界的能力,对于泛型类是这样的:

    public class Test<T extends Annotation> {
        
        public void print(T t){
            System.out.println(t);
        }
    }
    

    对于泛型方法来说可以想到,既然泛型参数是定义在返回值之前,泛型边界也应该一块定义:

    public interface AnnotatedElement {
        
        <T extends Annotation> T getAnnotation(Class<T> annotationClass);
    }
    
    展开全文
  • Java中的泛型的使用

    千次阅读 2014-11-24 15:59:24
    泛型的使用

    1.普通的泛型使用

    在使用类的时候后面的<>中的类型就是我们确定的类型。

    public class MyClass1<T> {//此处定义的泛型是T
        private T var;
    
        public T getVar() {
            return var;
        }
    
        public void setVar(T var) {
            this.var = var;
        }
    }
    /**
     * 最普通的泛型使用,只有一个泛型类型
     */
    @Test
    public void testMyClass1() {
        MyClass1<String> clazz = new MyClass1<String>();//此事确定对象对应的泛型T是String
        clazz.setVar("stringType");
        String str = clazz.getVar();
        System.out.println(str);
    }

    和普通的泛型使用基本一样,只是我们可以在使用类的时候定义两个不同的泛型类型,当然我们也可以定义多个,只要我们业务需要。

    public class MyClass2<K, V> {//此处定义两个泛型类型
        private K var1;//第一个变量的类型是K对应的具体类型
        private V var2;//第二个变量的类型是V对应的具体类型
    
        public K getVar1() {
            return var1;
        }
    
        public void setVar1(K var1) {
            this.var1 = var1;
        }
    
        public V getVar2() {
            return var2;
        }
    
        public void setVar2(V var2) {
            this.var2 = var2;
        }
    
    }
    
    /**
     * 含有两个泛型类型的使用
     */
    @Test
    public void testMyClass2() {
        //此处确定定义的clazz对象的第一个泛型类型是Integer,第二个泛型类型是String
        MyClass2<Integer, String> clazz = new MyClass2<Integer, String>();
        clazz.setVar1(1); //此处只能用int类型的参数
        clazz.setVar2("string");//此处只能用String类型的参数
    
        System.out.println(clazz.getVar1() + "," + clazz.getVar2());
    }

    这里面又包含3种:没限制的通配符、使用extends限制、使用super限制

    public class MyClass3<T> {
        private T var;
    
        public T getVar() {
            return var;
        }
    
        public void setVar(T var) {
            this.var = var;
        }
    
        @Override
        public String toString() {
            return var.toString();
        }
    
    }
    /**
     * 通配符?的使用 包括<?>、<?extends 类型>和<? super 类型>
     */
    @Test
    public void testMyClass3() {
        MyClass3<Boolean> clazz = new MyClass3<Boolean>();
        clazz.setVar(false);
        fun(clazz);//调运该方法的时候,对泛型没有限制,任何类型的泛型都可以使用
    
        MyClass3<Integer> clazzInt = new MyClass3<Integer>();
        clazzInt.setVar(1);
        funExtends(clazzInt);//调运该方法的时候,只能使用Number类型或者其子类型
    
        MyClass3<Double> clazzDouble = new MyClass3<Double>();
        clazzDouble.setVar(2.2);
        funExtends(clazzDouble);//调运该方法的时候,只能使用Number类型或者其子类型
    
    
        MyClass3<String> clazzString = new MyClass3<String>();
        clazzString.setVar("string");
        funSuper(clazzString);//调运该方法的时候,只能使用String类型或者其父类型
    
    
        MyClass3<Object> clazzObject = new MyClass3<Object>();
        clazzObject.setVar(new Object());
        funSuper(clazzObject);//调运该方法的时候,只能使用String类型或者其父类型
    
    }
    
    public void fun(MyClass3<?> clazz) {//没有限制的泛型使用
        System.out.println(clazz);
    }
    
    public void funExtends(MyClass3<? extends Number> clazz) {//只能使用Number及其子类的泛型
        System.out.println(clazz);
    }
    
    public void funSuper(MyClass3<? super String> clazz) {//只能使用String及其父类的泛型
        System.out.println(clazz);
    }

    4.定义类的时候就对泛型进行限制

    public class MyClass4<T extends Number> {//定义类的泛型的时候进行泛型的限制
        private T var;
    
        public T getVar() {
            return var;
        }
    
        public void setVar(T var) {
            this.var = var;
        }
    
        @Override
        public String toString() {
            return this.var.toString();
        }
    
    }
    
    /**
     * 定义类的泛型的时候都给定泛型的限制
     */
    @Test
    public void testMyClass4() {
        //同样只能定义Number及其子类的泛型
        // MyClass4<String> clazzString = new MyClass4<String>();
        MyClass4<Integer> clazzInt = new MyClass4<Integer>();
        MyClass4<Double> clazzDouble = new MyClass4<Double>();
    
        MyClass4<Float> clazzFClass4 = fun(1.1f);
        //此处调运的参数是float类型,这就确定了返回类型必须是float
    }
    
    public <T extends Number> MyClass4<T> fun(T arg) {
        return new MyClass4<T>();
    
    }
    public interface MyInterface<T> {
        public T getVar();
    }
    
    //两种实现方式。1,在实现的时候还是使用泛型,到具体定义对象的时候再确定
    public class MyInterface1Impl<T> implements MyInterface<T> {
        private T var;
    
        public MyInterface1Impl() {
        }
    
        public MyInterface1Impl(T var) {
            this.var = var;
        }
    
        @Override
        public T getVar() {
            return this.var;
        }
    
    }
    //第二种实现方式,在实现的时候就确定泛型的类型
    public class MyInterface2Impl implements MyInterface<String> {
        private String varStr;
    
        public MyInterface2Impl() {
        }
    
        public MyInterface2Impl(String varStr) {
            this.varStr = varStr;
        }
    
        @Override
        public String getVar() {
            return this.varStr;
        }
    }
    
    /**
     * 泛型接口的使用
     */
    @Test
    public void testMyInterface() {
        //实现类可以定义为任意类型的泛型
        MyInterface1Impl<String> varStr = new MyInterface1Impl<String>("abc");
        System.out.println(varStr.getVar());
        MyInterface1Impl<Integer> varInt = new MyInterface1Impl<Integer>(123);
        System.out.println(varInt.getVar());
    
        //之前已经在类实现的时候已经确定了只能是String
        MyInterface2Impl var = new MyInterface2Impl("cba");
        String str = var.getVar();
        System.out.println(str);
    }
    public class MyFunction {
        public <T> T fun1(T arg) {//传入参数和返回参数都是同样的泛型类型
            return arg;
        }
    
        public <T> void fun2(T arg) {//传入参数是泛型,不需要返回
            if (arg instanceof String) {
                System.out.println("T is StringType");
            } else if (arg instanceof Integer) {
                System.out.println("T is IntegerType");
            } else {
                System.out.println("T is OtherType");
            }
        }
    
        public <T> String fun3(T arg) {//传入的参数是泛型,返回的确定类型
            return arg.toString();
        }
    }
    
    /**
     * 泛型方法的使用
     */
    @Test
    public void MyFunction() {
        MyFunction clazz = new MyFunction();
        
        //传入什么类型,返回什么类型
        String var1 = clazz.fun1("abc");
        int var2 = clazz.fun1(12);
        System.out.println(var1);
        System.out.println(var2);
    
        //无论传入的是什么类型,都没关系
        clazz.fun2(1);
        clazz.fun2(false);
        clazz.fun2("string");
    
        //无论传入什么,都返回的是String
        String var3 = clazz.fun3(123);
        String var4 = clazz.fun3("string");
        System.out.println(var3);
        System.out.println(var4);
    
    }
    /**
     * 泛型数组的使用
     */
    @Test
    public void testArray(){
        Integer[] arr = fun(1,2,3);
       
    }
    
    public <T> T[] fun(T... args){//传入什么类型,T就是什么类型,并且可以使用泛型遍历
        for(T t:args){
            System.out.println(t.toString());
        }
        return args;
    }
    /**
     * 嵌套泛型
     */
    @Test
    public void testNest(){
        //外层泛型的类型其实就是内层泛型,当内层泛型确定了,那外层泛型也就确定了
        MyClass1<MyClass2<Integer, String>> nestOut = new MyClass1<MyClass2<Integer,String>>();
        MyClass2<Integer, String> nestIn = new MyClass2<Integer,String>();
        nestIn.setVar1(1);
        nestIn.setVar2("a");
        nestOut.setVar(nestIn);
        System.out.println(nestOut.getVar().getVar1());
        System.out.println(nestOut.getVar().getVar2());
    }
    展开全文
  • java泛型的使用

    2018-11-14 19:01:07
    java泛型的使用 泛型的产生机制就是放什么类型的数据进去,取出来的就是什么类型,而不用进行类型转换 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数...

    java泛型的使用

    泛型的产生机制就是放什么类型的数据进去,取出来的就是什么类型,而不用进行类型转换

    泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

    泛型是在编译阶段有效

    Java 泛型只在编译阶段有效,即在编译过程中,程序会正确的检验泛型结果。而编译成功后,class 文件是不包含任何泛型信息的

    使用泛型可以指代任意对象类型;

    泛型类

    public class CC<T>{
     
        private T ob;
     
         
        public CC(T ob) {
            super();
            this.ob = ob;
        }
     
        public T getOb() {
            return ob;
        }
     
        public void setOb(T ob) {
            this.ob = ob;
        }
         
        /**
         * 打印T的类型
         */
        public void print(){
            System.out.println("T的实际类型是:"+ob.getClass().getName());
        }
         
    }
    
    

     

            // begin test CC
            CC<Integer> cc=new CC<Integer>(1);
            cc.print();
            int icc=cc.getOb();
            System.out.println("i3="+icc);
             
            CC<String> cc2=new CC<String>("我是泛型,好简单啊");
            cc2.print();
            String icc2=cc2.getOb();
            System.out.println("s2="+icc2);
            // end test CC


     

    泛型方法

    public class Box<T> {
        private T box;
        public T getBox(T t){
            this.box = t;
            return t;
        }
        public void getType(){
            System.out.println("T的实际类型为:"+box.getClass().getName());
        }
         
        public static void main(String[] args) {
            Box box = new Box();
            System.out.println(box.getBox(1));
            box.getType();
             
            System.out.println(box.getBox("Tom"));
            box.getType();
        }
     
    }
    T的实际类型为:java.lang.Integer<br>
    Tom
    T的实际类型为:java.lang.String

     

    返回值为任意类型的泛型

    	public static <T> void f(T t){
    		System.out.println("T的类型是:"+t.getClass().getName());
    	}
    	
    	public static void main(String[] args) {
    		f("");
    		f(1);
    		f(1.0f);
    		f(new Object());
    	}

    泛型通配符

    在泛型中,我们可以用 ? 来代替任意类型

    public List wildCard(List<?> list){
         
        return list;
    }
     
    public static void main(String[] args) {
        GenericTest gt = new GenericTest();
        //构造一个 Interger 类型的集合
        List<Integer> integer = new ArrayList<Integer>();
        integer.add(1);
        System.out.println(gt.wildCard(integer));
        //构造一个 String 类型的集合
        List<String> str = new ArrayList<String>();
        gt.wildCard(str);
        //构造一个 Object 类型的集合
        List<Object> obj = new ArrayList<Object>();
        obj.add(1);
        obj.add("a");
        System.out.println(gt.wildCard(obj));
        //构造一个 任意类型的 集合,这和 List<Object> 存放数据没啥区别
        List list = new ArrayList();
        gt.wildCard(list);
         
    }
    	private static void take(Demo<?> a){
    		a.print();
    	}
    	
    	public static void main(String[] args) {
    		Demo<Dog> demo=new Demo<Dog>(new Dog());
    		take(demo);
    		
    		Demo<Cat> demo2=new Demo<Cat>(new Cat());
    		take(demo2);
    	}

    泛型的上限和下限

    ①、上限: 语法(? extends className),即只能为 className 或 className 的子类

    //通配符的下限,只能是 Number 或 Number的子类
        public List wildCard(List<? extends Number> list){
             
            return list;
        }
     
        public static void main(String[] args) {
            GenericTest gt = new GenericTest();
            //构造一个 Interger 类型的集合
            List<Integer> integer = new ArrayList<Integer>();
            integer.add(1);
            System.out.println(gt.wildCard(integer));
            //构造一个 String 类型的集合
            List<String> str = new ArrayList<String>();
            //gt.wildCard(str);   //编译报错
            //构造一个 Object 类型的集合
            List<Object> obj = new ArrayList<Object>();
            obj.add(1);
            obj.add("a");
            //System.out.println(gt.wildCard(obj)); //编译报错
             
        }

    下限: 语法(? super className),即只能为 className 或 className 的父类

    //通配符的上限,只能是 Number 或 Number的父类
        public List wildCard(List<? super Number> list){
             
            return list;
        }
     
        public static void main(String[] args) {
            GenericTest gt = new GenericTest();
            //构造一个 Interger 类型的集合
            List<Integer> integer = new ArrayList<Integer>();
            integer.add(1);
            //System.out.println(gt.wildCard(integer));  //编译报错
            //构造一个 String 类型的集合
            List<String> str = new ArrayList<String>();
            //gt.wildCard(str);   //编译报错
            //构造一个 Object 类型的集合
            List<Object> obj = new ArrayList<Object>();
            obj.add(1);
            obj.add("a");
            System.out.println(gt.wildCard(obj));
        }
     
    public class Animal {
     
        public void print(){
            System.out.println("动物");
        }
    }
    
    public class Dog extends Animal{
     
        public void print(){
            System.out.println("Dog");
        }
    }
    
    public class Cat extends Animal{
     
        public void print(){
            System.out.println("Cat");
        }
    }
    
    public class Demo <T extends Animal>{
     
        private T ob;
     
        public T getOb() {
            return ob;
        }
     
        public void setOb(T ob) {
            this.ob = ob;
        }
     
        public Demo(T ob) {
            super();
            this.ob = ob;
        }
         
        public void print(){
            System.out.println("T的类型是:"+ob.getClass().getName());
        }
    }
    
    public class Test {
     
        public static void main(String[] args) {
            Demo<Dog> demo=new Demo<Dog>(new Dog());
            Dog dog=demo.getOb();
            dog.print();
             
             
            Demo<Cat> demo2=new Demo<Cat>(new Cat());
            Cat cat=demo2.getOb();
            cat.print();
             
            Demo<Animal> demo3=new Demo<Animal>(new Animal());
        }
    }
    

    不能用基本类型来定义泛型,如 int、float

    如果使用 ? 接收泛型对象时,则不能设置被泛型指定的内容

    List<?> list = new ArrayList<>();
            list.add("aa");  //错误,无法设置

    泛型方法的定义与其所在的类是否是泛型类是没有任何关系的,所在的类可以是泛型类,也可以不是泛型类

    泛型类没有继承关系,即String 为 Object 类型的子类,则 List<String> 是 List<Object> 的子类这句话是错误的

     public static <T> List<T> asList(T... a) {
            return new ArrayList<>(a);
        }
     String[] str = {"a","b","c"};
     List listStr = Arrays.asList(str);
     System.out.println(listStr.size());//3
     int[] i = {1,2,3};
     List listI = Arrays.asList(i);
     System.out.println(listI.size());//1

    上面的结果第一个listStr.size()==3,而第二个 listI.size()==1。这是为什么呢?

      我们看源码,在 Arrays.asList 中,方法声明为  <T> List<T> asList(T... a)。该方法接收一个可变参数,并且这个可变参数类型是作为泛型的参数。我们知道基本数据类型是不能作为泛型的参数的,但是数组是引用类型,所以数组是可以泛型化的,于是 int[] 作为了整个参数类型,而不是 int 作为参数类型。

      所以将上面的方法泛型化补全应该是:

      String[] str = {"a","b","c"};
      List<String> listStr = Arrays.asList(str);
      System.out.println(listStr.size());//3
      
      int[] i = {1,2,3};
      List<int[]> listI = Arrays.asList(i);//注意这里List参数为 int[] ,而不是 int
      System.out.println(listI.size());//1
      
      Integer[] in = {1,2,3};
      List<Integer> listIn = Arrays.asList(in);//这里参数为int的包装类Integer,所以集合长度为3
      System.out.println(listIn.size());//3

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 关于泛型的使用

    2018-03-23 18:30:12
    今天准备继续看看springMVC的源码的,但是实在是看不下去了,惭愧惭愧,所以来总结一下泛型的使用(好像没什么逻辑)。泛型的介绍就就不多说了,要我说我也说不清楚。。。引用一句话:泛型类型在逻辑上可以看成是多...

    今天准备继续看看springMVC的源码的,但是实在是看不下去了,惭愧惭愧,所以来总结一下泛型的使用(好像没什么逻辑)。

    泛型的介绍就就不多说了,要我说我也说不清楚。。。引用一句话:泛型类型在逻辑上可以看成是多个不同的类型,实际上都是相同的基本类型。泛型的使用主要分为:泛型类,泛型接口,泛型方法。我们平时一般使用泛型就是在Map、List加入泛型类型,会有一种泛型就这样的感觉,事实上这是因为API给你创建好了泛型接口,你只是去使用,所以没有感觉到泛型的作用,去深入了解之后,你会发现泛型还是有点意思,有点思想在里面的。

    泛型类:就是在类上加个泛型,哈哈哈,好吧,这个解释有点勉强,直接上点代码吧:


    运行结果:


    主要使用场景就是,我们在创建类的时候,有一些属性不能确定其类型,而在使用的时候又想要约束其具体类型(因为使用Object做类型转换的时候,很容易出错),这个时候泛型就登场了,跟组合有点像,运行时确定具体的实现。

    泛型接口:

    泛型接口和泛型类的作用是差不多的,作用对象不一样,泛型接口就一点不同,当具体的类实现泛型接口时,你有两种选择,一是在类上继续选择泛型,在具体的使用时再去确定类型,二是直接选择具体的类型,但是你不能不写,这样是会报错的,上点代码:





    这样看就很明显了吧。

    泛型方法:

    泛型方法有两种,一种是在泛型类里面的泛型方法,这种方法的泛型和类的泛型是一样的。一种是和泛型类无关的泛型方法,泛型是让方法自己确定的,日常上代码:


    大概就是这样了。

    另外,泛型不支持父类做形参,而实参传入子类的,这个时候就需要使用泛型通配符了,就是那个问号<?>,还有泛型支持可变参数就是那个省略号T...,因为下班了,所以我就不写了。总的来说,泛型就是为了处理那些还不能确定是什么类型,但在具体使用时却要约束成具体的类型的场景。

    展开全文
  • Java-泛型的使用

    2020-02-26 18:09:22
    1.2 泛型的使用 1.2.1 泛型在方法上的使用(使用的是静态方法) 声明格式: public static <T> T(返回值类型) 方法名(一个对应泛型的参数) { //方法体 } 自定义的泛型声明在返回值之前,保...
  • 泛型的使用与通配符

    2020-07-06 09:21:17
    泛型的使用 1.jdk1.5新特性泛型 把元素的类型设计成一个参数,这个参数类型叫做泛型。 2.为什么要使用泛型? 类型无限制,类型不安全。 类型强制转换时,容易出现异常。ClassCastException 3.在集合中使用泛型 ...
  • 泛型的使用总结

    2015-06-21 20:27:17
    泛型的使用总结
  • 文章目录泛型泛型类的定义泛型类的使用类型擦除泛型类的使用-通配符通配符-上界通配符-下界泛型中的父子类型泛型方法泛型的限制 泛型 泛型类的定义 语法 class 泛型类名称<类型形参列表> { // 这里可以使用...
  • 目录泛型的概念使用泛型的好处泛型的使用泛型的定义自定义泛型结构自定义泛型类、泛型接口自定义泛型方法泛型在继承上的体现泛型中通配符的使用 泛型的概念       所谓泛型,就是允许...
  • Java中接口泛型的使用

    2020-10-02 13:52:48
    Java中接口泛型的使用 1.接口 package 泛型; public interface Interface<I> { public abstract void fun(I i); } 2.实现类 package 泛型; public class Impl<I> implements Interface<I>{ ...
  • java中泛型的使用

    2017-03-07 22:44:10
    泛型的使用对于代码质量的提高有很多作用。泛型可以增加程序的可读性,可以使代码得到一定程度的复用。不使用泛型时,如果是装入集合操作,那么元素都被当做Object对待,失去自己的类型,那么从集合中取出来时, ...

空空如也

1 2 3 4 5 ... 20
收藏数 30,944
精华内容 12,377
关键字:

泛型的使用