Java范型类

  1. public class FanXingClassTest {
  2. public static void main(String args[]){
  3. Test<Integer> intObj = new Test<Integer>(123);
  4. Test<String> strObj = new Test<String>("一二三");
  5. intObj.showType();
  6. strObj.showType();
  7. }
  8. }
  9.  
  10. /**
  11. * 定义范型类
  12. * @param <T>
  13. */
  14. class Test<T>{
  15. private T ob; //定义范型的成员变量
  16.  
  17. public Test(T ob){
  18. this.ob = ob;
  19. }
  20.  
  21. public void setT(T ob){
  22. this.ob = ob;
  23. }
  24. public T getT(){
  25. return this.ob;
  26. }
  27.  
  28. public void showType(){
  29. System.out.println("T的实际类型是:"+ob.getClass());
  30. }
  31. }

  对比一下没有使用范型类(如下代码),也可以输出一样的结果,为什么要使用范型类?类型检查??

  1. public class FanXingClassTest {
  2. public static void main(String args[]){
  3. Test intObj = new Test(123);
  4. Test strObj = new Test("一二三");
  5. intObj.showType();
  6. strObj.showType();
  7. }
  8. }
  9. /**
  10. * 定义普通类
  11. */
  12. class Test{
  13. private Object ob; // 不能定义T类型的变量??
  14.  
  15. public Test(Object ob){
  16. this.ob = ob;
  17. }
  18.  
  19. public void setT(Object ob){
  20. this.ob = ob;
  21. }
  22. public Object getT(){
  23. return this.ob;
  24. }
  25.  
  26. public void showType(){
  27. System.out.println("T的实际类型是:"+ob.getClass());
  28. }
  29. }

我们做实验如下:

  1. // 两个基本类:StringDemo和DoubleDemo
  2. public class StringDemo {
  3. private String str;
  4.  
  5. public StringDemo(String str){
  6. this.str = str;
  7. }
  8.  
  9. public void setStr(String str){
  10. this.str = str;
  11. }
  12. public String getStr(){
  13. return this.str;
  14. }
  15. }
  16. public class DoubleDemo {
  17. private Double doubleVal;
  18.  
  19. public DoubleDemo(Double doubleVal){
  20. this.doubleVal = doubleVal;
  21. }
  22. public void setDoubleVal(Double doubleVal){
  23. this.doubleVal = doubleVal;
  24. }
  25. public Double getDoubleVal(){
  26. return this.doubleVal;
  27. }
  28. }
  29.  
  30. // 因为上面的类中,成员和方法的逻辑都一样,就是类型不一样,因此考虑重构。Object是所有类的父类,因此可以考虑用Object做为成员类型,这样就可以实现通用了,实际上就是“Object泛型”,暂时这么称呼。
  31. public class ObjectDemo {
  32. private Object obj;
  33.  
  34. public ObjectDemo(Object obj){
  35. this.obj = obj;
  36. }
  37. public void setObj(Object obj){
  38. this.obj = obj;
  39. }
  40. public Object getObj(){
  41. return this.obj;
  42. }
  43. }
  44. public class MyDemo {
  45. public static void main(String args[]){
  46. ObjectDemo str = new ObjectDemo("string");
  47. ObjectDemo dble = new ObjectDemo(123d);
  48. ObjectDemo obj = new ObjectDemo(new Object());
  49. System.out.println(str.getObj());
  50. System.out.println(dble.getObj());
  51. System.out.println(obj.getObj());
  52. }
  53. }
  54.  
  55. // 在Java 5之前,为了让类有通用性,往往将参数类型、返回类型设置为Object类型,当获取这些返回类型来使用时候,必须将其“强制”转换为原有的类型或者接口,
    // 然后才可以调用对象上的方法。强制类型转换很麻烦,我还要事先知道各个Object具体类型是什么,才能做出正确转换。否则,要是转换的类型不对,比如将
    // “Hello Generics!”字符串强制转换为Double,那么编译的时候不会报错,可是运行的时候就挂了。那有没有不强制转换的办法----有,改用 Java5泛型来实现,
    // 示例见最上面FanXingClassTest<T>范型类的定义。

范型类语法解释

  1. 1. 使用<T>来声明一个类型持有者名称,然后就可以把T当作一个类型代表来声明成员、参数和返回值类型。
  2. 2. class GenericsTest<T> 声明了一个泛型类,这个T没有任何限制,实际上相当于Object类型,实际上相当于 class GenericsTest<T extends Object>。
  3. 3. Object泛型类相比,使用泛型所定义的类在声明和构造实例的时候,可以使用“<实际类型>”来一并指定泛型类型持有者的真实类型。类如
  4. GenericsTest<Double> douTest=new GenericsTest<Double>(new Double("33"));
  5. 4. 实际上,当构造对象时不指定类型信息的时候,默认会使用Object类型,这也是要强制转换的原因.

限制范型

  在上面的例子中,由于没有限制class GenericsTest<T>类型持有者T的范围,实际上这里的限定类型相当于Object,这和“Object泛型”实质是一样的。限制比如我们要限制T为集合接口类型。只需要这么做:class GenericsTest<T extends Collection>,这样类中的泛型T只能是Collection接口的实现类,传入非Collection接口编译会出错。注意:<T extends Collection>这里的限定使用关键字extends,后面可以是类也可以是接口。但这里的extends已经不是继承的含义了,应该理解为T类型是实现Collection接口的类型,或者T是继承了XX类的类型。
  1. // 限制范型
  2. public class CollectionGenTest<T extends Collection> {
  3. private T x;
  4. public CollectionGenTest(T x){
  5. this.x = x;
  6. }
  7. public T getX(){
  8. return this.x;
  9. }
  10. public void setX(T x){
  11. this.x = x;
  12. }
  13. }
  14. public class CollectionGenTestDemo {
  15. public static void main(String args[]){
  16. CollectionGenTest<ArrayList> test = new CollectionGenTest<ArrayList>(new ArrayList());
  17. System.out.println("实例化完成");
  18. }
  19. }
  20.  
  21. // 多接口限制
    <T extends SomeClass & interface1 & interface2 & interface3>
  22.  
  23. // 通配符范型
    <T extends Collection> //向下限制
    <?> //任意类型,相当于Object
    <T super Double> // 向上限制,Double类型或者其父类

Java范型方法

  1. /**
  2. * 范型方法:只需在返回值前添加<T>
  3. */
  4. public class ExampleA {
  5. public <T> void f(T x){
  6. System.err.println(x.getClass().getName());
  7. }
  8.  
  9. public static void main(String args[]){
  10. ExampleA exampleA = new ExampleA();
  11. exampleA.f("");
  12. exampleA.f(123);
  13. exampleA.f('a');
  14. exampleA.f(exampleA);
  15. }
  16. }
  17.  
  18. // 使用泛型方法时,不必指明参数类型,编译器会自己找出具体的类型。泛型方法除了定义不同,调用就像普通方法一样
    // 一个static方法,无法访问泛型类的类型参数,所以,若要static方法需要使用泛型能力,必须使其成为泛型方法。

方法

1. 定义泛型方法时,必须在返回值前边加一个<T>,来声明这是一个泛型方法,

2. Class<T>的作用就是指明泛型的具体类型,而Class<T>类型的变量c,可以用来创建泛型类的对象。为什么要用变量c来创建对象呢?既然是泛型方法,就代表着我们不知道具体的类型是什么,也不知道构造方法如何,因此没有办法去new一个对象,但可以利用变量c的newInstance方法去创建对象,也就是利用反射创建对象。

3.   http://www.cnblogs.com/iyangyuan/archive/2013/04/09/3011274.html

范型方法 & 范型参数 & 范型返回值的更多相关文章

  1. 工作随笔——Java调用Groovy类的方法、传递参数和获取返回值

    接触Groovy也快一年了,一直在尝试怎么将Groovy引用到日常工作中来.最近在做一个功能的时候,花了点时间重新看了下Java怎么调用Groovy的方法.传递参数和获取返回值. 示例Groovy代码 ...

  2. C++ 调用Python文件方法传递字典参数并接收返回值

    首先本地需要安装有Python环境,然后在c++工程中包含Python的头文件,引用Python的lib库. //python 初始化 Py_Initialize(); if (!Py_IsIniti ...

  3. 写一方法用来计算1+2+3+...n,其中n作为参数输入,返回值可以由方法名返回,也可以由参数返回

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  4. atitit.架构设计---方法调用结果使用异常还是返回值

    atitit.架构设计---方法调用结果使用异常还是返回值 1. 应该返回BOOL类型还是异常 1 2. 最终会有四种状况,抛出异常.返回特殊值.阻塞.超时 1 3. 异常的优缺点点 1 4. jav ...

  5. FiddlerScript修改特定请求参数下的返回值

    使用场景: api/Live/GetLiveList接口: (1)Type为1,接口返回直播列表 (2)Type为2,接口返回回放列表 现在想修改直播列表的返回值 思路: 利用FiddlerScrip ...

  6. python限定方法参数类型、返回值类型、变量类型等

    typing模块的作用 自python3.5开始,PEP484为python引入了类型注解(type hints) 类型检查,防止运行时出现参数和返回值类型.变量类型不符合. 作为开发文档附加说明,方 ...

  7. java方法强制传递引用参数(做为返回值),改变被传递参数值。

    Java传递参数分为2种: 值类型,Java里面也叫简单类型,这种参数类型的传递的是它的副本拷贝: 引用类型,传递的是对象引用地址,如果在方法内改变该参数对象属性即是对原引用对象的改变:如果不想这样传 ...

  8. C++对象内存布局,this指针,对象作为参数,作为返回值

    class TestClass { public: void setNum(int num) { m_num1 = num; } int getNum() { return m_num1; } pri ...

  9. Spring-boot 配置Aop获取controller里的request中的参数以及其返回值

    首先在你的Maven的pom文件里加入aop的依赖: <dependency> <groupId>org.springframework.boot</groupId> ...

  10. JS中函数参数和函数返回值的理解

    函数本质就是功能的集合 JS中函数是对象,因此,函数名实际上仅仅是一个指向函数对象的指针,不会与某个函数绑定,所以,JS中没有重载(重载就是通过传递不同类型的参数,使两个相同函数名的函数执行不同的功能 ...

随机推荐

  1. 分布式存储MooseFS

    MooseFS 简介 http://moosefs.org/ MFS特性 安装和配置简单方便   可靠性高(数据的多个拷贝被存储在多个不同的服务器上)   通过添加新的服务器或硬盘就可以实现容量的动态 ...

  2. CF871D Paths

    link 题意: n个点的无向图,若$\gcd(x,y) \neq1​$则$(x,y)​$有边,统计$1\sim n​$构成的无向图两两点对最短路是之和是多少(两点不连通最短路记为0)?$n\leq ...

  3. RabbitMQ主题模式

    Send类 package topics; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; imp ...

  4. CentOS 7 安装MongoDB详细步骤

    创建/etc/yum.repos.d/mongodb-org-4.0.repo文件,编辑内容如下: [mongodb-org-4.0] name=MongoDB Repository baseurl= ...

  5. php 通用数据库类

    <?php // 数据库连接类 class DB{ //私有的属性 private static $dbcon=false; private $host; private $port; priv ...

  6. 1084: 开心的小明(dengdengoj)

    题目描述 小明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N 元钱就行”.今 ...

  7. ubuntu 配置

    这是安装语言包 sudo apt-get install language-pack-touch-zh-hans language-pack-touch-zh-hant 这是安装字体 sudo apt ...

  8. Java weak reference

    一个对象被回收,必须满足两个条件: 没有任何引用指向它和GC在运行.把所有指向某个对象的引用置空来保证这个对象在下次GC运行时被回收. Object c = new Car(); c = null; ...

  9. 关于js函数对象的理解

    js中函数和对象的关系: 什么是对象?根据W3C上面的解释JS中所有事物都是对象,对象是拥有属性和方法的数据,由此可以看出除了基 本值类型不是对象(number.string.Boolean.Unde ...

  10. 一款好用的轮播插件swiper,适用于移动端和web

    swiper的dom布局 <div id="commentsSwiper" class="swiper-container"> <div cl ...