精华内容
下载资源
问答
  • 关于泛型通配符与泛型限定

    千次阅读 2017-08-23 10:08:45
    Java中泛型是在不确定具体使用哪个类型的时候进行的泛型处理,这样可以匹配多个数据类型。 而通配符 ? 是一种泛型的手段,通过一个占位符,将所需要的数据类型,不显示的说明,只是在那里模糊的占位,表示有那么一...

    Java中泛型是在不确定具体使用哪个类型的时候进行的泛型处理,这样可以匹配多个数据类型。

    而通配符 ? 是一种泛型的手段,通过一个占位符,将所需要的数据类型,不显示的说明,只是在那里模糊的占位,表示有那么一个类型。这样在我们使用泛型时,不管是定义函数还是类,都可以轻松的使用泛型。

    泛型的限定:在于将泛型的通配符的作用域减小,本来泛型的通配符的作用域作用于所有的类型,但是有了限定可以将作用域大大减小,方便我们的功能实现。

    具体可以分为,向上,向下 

    向上:

    ? extends E: 可以接收E 类型或者是E类型的子类型 

    向下:

    ? super E 可以接收 E类型 或者是E类型的父类型

    下面使用一段代码来进行说明和比较,这样比较直观,可以更好的看出他们的区别:

    package mypack;
    /**
     * 泛型限定:
     * ? 通配符 :也可以理解为占位符
     * 泛型的限定:
     * ? extends E: 可以接收E 类型或者是E类型的子类型
     * ? super E 可以接收 E类型 或者是E类型的父类型
     */
    import java.util.ArrayList;
    import java.util.Iterator;
    
    public class Fanxingxiand {
    	public static void main(String[] args) {
    		ArrayList<Persons> persons = new ArrayList<Persons>();
    		persons.add(new Persons("aaa"));
    		persons.add(new Persons("bbb"));
    		persons.add(new Persons("ccc"));
    		//打印父类
    		print1(persons);
    		print2(persons);
    		print3(persons);
    		ArrayList<Student> students = new ArrayList<Student>();
    		students.add(new Student("111"));
    		students.add(new Student("333"));
    		students.add(new Student("222"));
    		//打印子类
    		//print(students);   是错误的,print函数是父类的,比较大,子类不能使用
    		print1(students);
    		print2(students);
    		print3(students);
    		
    		//打印无关类
    		ArrayList<Dogs> dogs = new ArrayList<Dogs>();
    		dogs.add(new Dogs("dog1"));
    		dogs.add(new Dogs("dog2"));
    		dogs.add(new Dogs("dog3"));
    		dogs.add(new Dogs("dog4"));
    		print1(dogs); //可以打印
    		//print2(dogs);  //编译出错不能打印
    		//print3(dogs); //编译出错不能打印
    		
    		
    	}
    	/*
    	第一种 : 只能打印父类的、
    	public static void print(ArrayList<Persons> persons){
    		Iterator<Persons> it = persons.iterator();
    		while(it.hasNext()){
    			System.out.println(it.next().getName());
    		}
    	}*/
    	
    	
    	/*第二种,打印所有
    	 * 可以都讲他们打印出来,但是这个是将什么类型的元素都可以打印出来
    	 * */
    	public static void print1(ArrayList<?> persons){
    		Iterator<?> it = persons.iterator();
    		while(it.hasNext()){
    			System.out.println(it.next().toString());
    		}
    	}
    	
    	
    	/*
    	 * 3 。 泛型限定,作用是可以只能打印 Persons 和其子类的的数据 ,其他不能打印。
    	 * */
    	public static void print2(ArrayList<? extends Persons> persons){
    		Iterator<? extends Persons> it = persons.iterator();
    		while(it.hasNext()){
    			System.out.println(it.next().toString());
    		}
    	}
    	
    	public static void print3(ArrayList<? super Student> persons){
    		Iterator<? super Student> it = persons.iterator();
    		while(it.hasNext()){
    			System.out.println(it.next().toString());
    		}
    	}
    }
    
    
    class Persons {
    	private String name;
    	Persons(){}
    	Persons(String name){this.name = name;}
    	public String getName(){
    		return name;
    	}
    	@Override
    	public String toString() {
    		return "Persons [name=" + name + "]";
    	}
    	
    	
    }
    
    class Student extends Persons{
    	Student(){}
    	Student(String name){super(name);}
    }
    
    
    class Dogs{
    	private String name;
    	Dogs(){}
    	Dogs(String name){this.name = name;}
    	public String getName(){
    		return name;
    	}
    	@Override
    	public String toString() {
    		return "Dogs [name=" + name + "]";
    	}
    }



    展开全文
  • 关于泛型的理解

    千次阅读 2021-01-04 09:11:27
    ** 什么叫泛型? ** 个人理解是把重复的类进行一个整合防止类型膨胀,...(感觉就是有许多种泛型):泛型类,泛型接口,泛型委托,泛型方法 例子1 泛型类: static void Main(string[] args) { Apple apple = new

    什么叫泛型?

    以下为自己的个人理解:
    是把重复的类进行一个整合防止类型膨胀,成员膨胀。
    在定义一个类,接口,方法等的时候不明确定义类型用 <类型参数> 来定义,等要使用的时候再去明确定义,这就是泛型。

    类型参数是指一个泛化的类型,就是用一个标识符来表示,标识符是由自己命名,可以是ABD,DSD。

    泛型有正交性,个人理解是有许多种泛型:泛型类,泛型接口,泛型委托,泛型方法等等

    例子1 泛型类:
    下面是一个商店里的包装,商店里的苹果和书本用盒子装起来,因为苹果和书长不一样,所以我要使用不同的盒子。
    打个比方,苹果有不同颜色和牌子,有青苹果和红苹果,有富士山苹果等等,所以我要在苹果的盒子上写苹果的颜色(color)和牌子(brand),书有很多,每本书的作者也可能不一样,比如哈姆雷特是莎士比亚写的,悲惨世界是雨果写的,在书的盒子外面要写上作者(Author)和名字(Name)来区分。
    于是就有了苹果盒子(AppleBox),书本盒子(BookBox),但是他们本质上都是盒子,那么我们可以先把盒子买来,但是先不决定它是什么盒子(假设这里的这个盒子贴上啥标签就会变成什么盒子),等要用盒子的时候,再给这个盒子贴上标签来确定是苹果盒子还是书本盒子。
    我的苹果和书本分别是Apple和Book类型,把盒子定义为一个泛型类(Box),它的类型定义为,TCargo是我自己的定义的,表示货物类型,这个<>里面的标识符由自己定义,当我要使用盒子的时候,就把TCargo改为我要装进去的物品类型,比如是书本盒子就变成Box,以下是具体例子

            static void Main(string[] args)
            {
                Apple apple = new Apple { Color = "Red" ,Brand="富士山"};
                Book book = new Book { Name = "哈姆雷特" ,Author="莎士比亚"};
                Box<Apple> box1 = new Box<Apple> { Cargo = apple };
                Box<Book> box2 = new Box<Book> { Cargo = book };
                Console.WriteLine("苹果颜色:{0},牌子:{1}", box1.Cargo.Color,box1.Cargo.Brand);
                Console.WriteLine("书名:{0},作者:{1}",box2.Cargo.Name,box2.Cargo.Author);
            }
    
            class Apple
            {
                public string Color { get; set; }
                public string Brand { get; set; }
    
            }
    
            class Book
            {
                public string Name { get; set; }
                public string Author { get; set; }
    
            }
    
            class Box<TCargo>
            {
                public TCargo Cargo { get; set; }
            }
    

    运行结果
    在这里插入图片描述
    例子2 泛型接口:

    static void Main(string[] args)
        {
            Student<ulong> student = new Student<ulong> { };
    //使用接口时没有特化泛型接口
            student.ID = 10000000000001;
            student.Name = "莎士比亚";
    //使用接口时特化泛型接口
            Teacher teacher = new Teacher { };
            teacher.ID = 1000000000000001;
            teacher.Name = "孔子";
        }
    
        interface IUnique<TId>
        {
            TId ID { get; set; }
        }
    
    
    //使用接口时没有特化泛型接口
        class Student<TId> : IUnique<TId>
        {
            public TId ID { get; set; }
            public string Name;
        }
    
    //使用接口时特化泛型接口
        class Teacher : IUnique<ulong>
        {
            public ulong ID { get; set; }
            public string Name;
        }
    }
    

    例子3 泛型方法

    static void Main(string[] args)
    {
        int[] a1 = { 1, 3, 5, 7 };
        int[] a2 = { 2, 4, 6, 8 };
        double[] a3 = { 1.1, 3.3, 5.5, 7.7 };
        double[] a4 = { 2.2, 4.4, 6.6, 8.8 };
        var result = zip(a1, a2);
        Console.WriteLine(string.Join(",", result));
    }
    
    static T[] zip<T>(T[] a, T[] b)
    {
        T[] zipped = new T[a.Length + b.Length];
        int ai = 0, bi = 0, zi = 0;
        do
        {
            if (ai < a.Length)
            {
                zipped[zi++] = a[ai++];
            }
    
            if (bi < b.Length)
            {
                zipped[zi++] = b[bi++];
            }
        } while (ai < a.Length || bi < b.Length);
        return zipped;
    }
    

    小笔记

    记一下,以后有问题再回来改,如果有错误也可以在评论区指出
    有待补充…

    展开全文
  • 有许多原因促成了泛型的出现,而最引人注意的一个原因,就是为了创建容器类。 泛型类 容器类应该算得上最具重用性的类库之一。先来看一个没有泛型的情况下的容器类如何定义: public class Container { ...

    有许多原因促成了泛型的出现,而最引人注意的一个原因,就是为了创建容器类。

    泛型类

    容器类应该算得上最具重用性的类库之一。先来看一个没有泛型的情况下的容器类如何定义:

    public class Container {
        private String key;
        private String value;
    
        public Container(String k, String v) {
            key = k;
            value = v;
        }
    
        public String getKey() {
            return key;
        }
    
        public void setKey(String key) {
            this.key = key;
        }
    
        public String getValue() {
            return value;
        }
    
        public void setValue(String value) {
            this.value = value;
        }
    }

    Container 类保存了一对 key-value 键值对,但是类型是定死的,也就说如果我想要创建一个键值对是 String-Integer 类型的,当前这个 Container 是做不到的,必须再自定义。那么这明显重用性就非常低。

    当然,我可以用 Object 来代替 String ,并且在Java SE5之前,我们也只能这么做,由于 Object 是所有类型的基类,所以可以直接转型。但是这样灵活性还是不够,因为还是指定类型了,只不过这次指定的类型层级更高而已,有没有可能不指定类型?有没有可能在运行时才知道具体的类型是什么?

    所以,就出现了泛型。

    public class Container<K, V> {
        private K key;
        private V value;
    
        public Container(K k, V v) {
            key = k;
            value = v;
        }
    
        public K getKey() {
            return key;
        }
    
        public void setKey(K key) {
            this.key = key;
        }
    
        public V getValue() {
            return value;
        }
    
        public void setValue(V value) {
            this.value = value;
        }
    }

    在编译期,是无法知道 K 和 V 具体是什么类型,只有在运行时才会真正根据类型来构造和分配内存。可以看一下现在 Container 类对于不同类型的支持情况:

    public class Main {
    
        public static void main(String[] args) {
            Container<String, String> c1 = new Container<String, String>("name", "findingsea");
            Container<String, Integer> c2 = new Container<String, Integer>("age", 24);
            Container<Double, Double> c3 = new Container<Double, Double>(1.1, 2.2);
            System.out.println(c1.getKey() + " : " + c1.getValue());
            System.out.println(c2.getKey() + " : " + c2.getValue());
            System.out.println(c3.getKey() + " : " + c3.getValue());
        }
    }

    输出:
    name : findingsea
    age : 24
    1.1 : 2.2

    泛型接口

    在泛型接口中,生成器是一个很好的理解,看如下的生成器接口定义:

    public interface Generator<T> {
        public T next();
    }

    然后定义一个生成器类来实现这个接口:

    public class FruitGenerator implements Generator<String> {
    
        private String[] fruits = new String[]{"Apple", "Banana", "Pear"};
    
        @Override
        public String next() {
            Random rand = new Random();
            return fruits[rand.nextInt(3)];
        }
    }

    调用:

    public class Main {
    
        public static void main(String[] args) {
            FruitGenerator generator = new FruitGenerator();
            System.out.println(generator.next());
            System.out.println(generator.next());
            System.out.println(generator.next());
            System.out.println(generator.next());
        }
    }

    输出:

    Banana
    Banana
    Pear
    Banana

    泛型方法

    一个基本的原则是:无论何时,只要你能做到,你就应该尽量使用泛型方法。也就是说,如果使用泛型方法可以取代将整个类泛化,那么应该有限采用泛型方法。下面来看一个简单的泛型方法的定义:

    public class Main {
    
        public static <T> void out(T t) {
            System.out.println(t);
        }
    
        public static void main(String[] args) {
            out("findingsea");
            out(123);
            out(11.11);
            out(true);
        }
    }

    可以看到方法的参数彻底泛化了,这个过程涉及到编译器的类型推导和自动打包,也就说原来需要我们自己对类型进行的判断和处理,现在编译器帮我们做了。这样在定义方法的时候不必考虑以后到底需要处理哪些类型的参数,大大增加了编程的灵活性。

    再看一个泛型方法和可变参数的例子:

    public class Main {
    
        public static <T> void out(T... args) {
            for (T t : args) {
                System.out.println(t);
            }
        }
    
        public static void main(String[] args) {
            out("findingsea", 123, 11.11, true);
        }
    }
    输出和前一段代码相同,可以看到泛型可以和可变参数非常完美的结合。

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

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

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

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

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


    运行结果:


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

    泛型接口:

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





    这样看就很明显了吧。

    泛型方法:

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


    大概就是这样了。

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

    展开全文
  • C# 关于泛型

    千次阅读 2014-03-28 17:43:06
    C#总结之 泛型 (1) 泛型的优点 泛型的使用主要是在集合中,在集合中非泛型是把类型转化为通用基类型Object,这样做虽然方便但是有两个缺点: 要进行装箱操作,拆箱操作,因此会降低性能 缺乏对类型检查,容易出错。...
  • 关于泛型、反射问题

    2020-08-17 14:18:48
    有个超类、子类、孙子类,我在子类中指明了泛型,结果在运行孙子类时,超类无法解析泛型,Type不能强制转换ParameterizedType,把泛型放在孙子类就是正常的。怎么解决?
  • 关于泛型的说法

    2019-07-04 21:34:56
    https://docs.oracle.com/javase/tutorial/java/generics/why.html
  • java关于泛型与自定义泛型的使用

    千次阅读 2013-03-13 17:05:58
    泛型的应用在java里也是很普遍的,jdk1.5之前,如果将一个String类型的对象添加到一个集合中,可能会出现这样的状况,由于程序员的疏忽,将String类型的对象转成了其他类型的对象。所以说,泛型的出现,解决了对象...
  • 关于泛型的理解-浅谈泛型

    千次阅读 2014-08-05 21:59:57
    1,泛型是在jdk1.5才有的概念。在jdk1
  • 简介:用通俗图文和比喻去理清一下泛型的结构和语法以及一些特点。 参考文章:https://www.cnblogs.com/yangming1996/p/9199557.html 目录: 1 泛型概述 2 定义泛型类/接口/方法 3 通配符 4 一些特点 泛型...
  • 关于泛型的一点理解

    2015-03-12 18:46:59
    为了在静态(static)方法中使用泛型类的类型参数(“T”),于是有了泛型方法,注意泛型方法的格式,类型参数需要放在函数返回值之前。 static void fromArrayToCollection(T[] a, Collectionc){ 边界通配符...
  • Fastjson关于泛型的 json 转 对象

    千次阅读 2018-11-20 11:10:43
    可以看到 cbk 是泛型,因为它可能是 一个 item 或者是一个 其他的 bean; 如果用传统的方式解析 json,如: BaseResponse<HotPotInfo> response = JSON.parseObject(s,BaseResponse.class); 虽然可以打印,但...
  • 解析关于泛型类型的细节信息的获取方法 Method与泛型相关的方法 ----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------ 以前对Method的讨论中,我们主要是通过Method类对象对...
  • Java中关于泛型的总结(转)

    千次阅读 2013-01-23 00:00:46
    一、Java泛型的实现方法:类型擦除 前面已经说了,Java的泛型是伪泛型。为什么说Java的泛型是伪泛型呢?因为,在编译期间,所有的泛型信息都会被擦除掉。正确理解泛型概念的首要前提是理解类型擦出(type erasure)...
  • 泛型27.优先考虑泛型方法 28.利用有限制通配符来提高API的灵活性 29.优先考虑类型安全的异构容器枚举30.用enum代替int常量 31.用实例域代替序数 32.用EnumSet代替位域 33.EnumMap代替序数索引 34.用接口模拟可...
  • 关于泛型的认识和理解

    万次阅读 2011-10-19 11:44:03
    今天学习了泛型的知识,以前在看毕向东老师的视频时,开始提到泛型,我的理解以为是上帝类Object呢。 今天看完高新视频后,对泛型有了新的理解。于是找了泛型的知识的特点。 在Java1.5后引入了泛型的概念。  ...
  • 作用1:当自定义的一个类中的所有方法都需要操作相同的数据类型并且这个数据类型暂时无法确定(在创建该类的实例时才确定),此时,我们可以通过在类名后面定义一个泛型,作为一个标识符,当该标记符被确定为某一个...
  • Android下关于泛型class类型的获取

    千次阅读 2018-05-16 13:57:59
    * 直接在createPresenter中拿到当前类的泛型的class,利用反射制造一个对象并返回 */ protected T createPresenter (){ //这里获得到的是类的泛型的类型 ParameterizedType type = (ParameterizedType) ...
  • 泛型泛型的机制出现原因:集合海纳百川,不同数据类型之间的调用需要转型操作,有时候还会冲突 泛型的作用:统一类型(免去转型的操作) 泛型的用法:在任何有的地方,把E换成你想要的任何类型 ...
  • 上午和hottey探讨了一下泛型技术。我问他Delphi是否有对泛型技术的支持,他回答说Delphi的泛型可以通过无类型指针来实现。无类型指针可以实现容器的泛型化,但是对于算法的泛型化就无能为力了。而且,用无类型指针...
  • 1在C++中还没有引进模板的...泛型可以在几乎无损于效率的情况下支持代码的高度可复用性,并且具有数学的抽象美(这一点接触过STL源码的人都非常清楚)。于是,泛型几乎立即就成了C++中举足轻重的特性之一。 2004-9-
  • 首先,java中有泛型擦除这一概念。如果不太了解这一概念的同学可以...进入主题,关于泛型擦除,但是反编译class文件泛型会出现的问题。以例子来说明 首先,先写一个使用了泛型的java文件 import org.junit.Test; imp
  • 关于泛型类、泛型方法和泛型接口,之前的章节已经或多或少涉及到,本章主要对这三种使用方法进行更为详细的学习。 1.泛型接口 泛型接口的使用较为简单,这里给出一个示例。 假设场景:某个演示程序需要开发一个...
  • 泛型集合和ArrayList的装箱拆箱、常见的泛型类型、泛型类和泛型方法、泛型约束、 泛型委托泛型很难理解?不然在接触的一个新的概念的时候,总会感觉难以理解,当你掌握并能熟练地使用的时候,发现这个概念其实简单...
  • 今天碰巧看了一段关于泛型的讲解,觉得泛型也没有自己想象中那么难,于是将自己的心得分享出来,希望能帮到有需要的人。 泛型的知识点大概有:泛型类,限制泛型泛型方法,泛型接口。 泛型类 下面泛型类的例子就...
  • 泛型数组+泛型嵌套+泛型应用实例

    千次阅读 2017-04-22 16:14:55
    泛型数组关于泛型方法-泛型接口和方法使用泛型方法时,也可以传递和返回一个泛型数组。 【接收和返回泛型数组】@SuppressWarnings("unchecked") public class GeneriseDemo30 { public static void main(String ...
  • 关于获取泛型的实际类型的方法

    千次阅读 2017-11-29 16:48:09
    我们在开发过程中有可能会遇不同类型的类,通过泛型的参数传到方法中...而关于泛型的使用,有两种,一种是最为面向对象的类进行开发,比如上面提到的Class&lt;T&gt; className ,另外一种是作为接口比如 publ...
  • 泛型

    2020-08-20 23:58:35
    泛型的参数类型可以用在类,接口和方法创建中分别称为:泛型类,泛型接口和泛型方法。 ArrayList<E>:整个称为泛型类型,E表示泛型变量或泛型参数 ArralyList<Integer>:整个称为参数化类型,Integer称为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 362,191
精华内容 144,876
关键字:

关于泛型