java 泛型

在Java SE1.5中,增加了一个新的特性:泛型(日本语中的总称型)。何谓泛型呢?通俗的说,就是泛泛的指定对象所操作的类型,而不像常规方式一样使用某种固定 的类型去指定。泛型的本质就是将所操作的数据类型参数化,也就是说,该数据类型被指定为一个参数。这种参数类型可以使用在类、接口以及方法定义中。

 

一、  为什么使用泛型呢?

     在以往的J2SE中,没有泛型的情况下,通常是使用Object类型来进行多种类型数据的操作。这个时候操作最多的就是针对该Object进行数据的强制 转换,而这种转换是基于开发者对该数据类型明确的情况下进行的(比如将Object型转换为String型)。倘若类型不一致,编译器在编译过程中不会报 错,但在运行时会出错。

    使用泛型的好处在于,它在编译的时候进行类型安全检查,并且在运行时所有的转换都是强制的,隐式的,大大提高了代码的重用率。

 

二、泛型的简单例子:

首先,我们来看看下面两个普通的class定义

public class getString {

private String myStr;

 

public String getStr() {

    return myStr;

}

 

public void setStr(str) {

    myStr = str;

}

}

 

public class getDouble {

private Double myDou;

 

public Double getDou() {

    return myDou;

}

 

public void setDou(dou) {

    myDou = dou;

}

          }

 

    这两个class除了所操作的数据类型不一致,其他机能都是相同的。现在,我们可以使用泛型来将上面两个class合并为一个,从而提高代码利用率,减少代码量。

        public class getObj<T> {

            private T myObj ;

           

            public T getObj() {

                return myObj;

            }

 

            public void setObj<T obj> {

                 myObj = obj;

              }

        }

 

    那么,使用了泛型后,如何生成这个class的实例来进行操作呢?请看下面的代码:

        getObj<String> strObj = new getObj<String>();

        strObj.setObj(“Hello Nissay”);

        System.out.println(strObj.getObj());

 

         getObj<Double> douObj = new getObj<Double>();

         douObj.setObj(new Double(“116023”));

         System.out.println(douObj.getObj());

 

三、例子分析

现在我们来分析上面那段蓝色字体的代码:

1、<T>是泛型的标记,当然可以使用别的名字,比如。使用<T>声明一个泛型的引用,从而可以在class、方法及接口中使用它进行数据定义,参数传递。

2、<T>在声明的时候相当于一个有意义的数据类型,编译过程中不会发生错误;在实例化时,将其用一个具体的数据类型进行替代,从而就可以满足不用需求。

 

四、 泛型的规则和限制

通过上述的例子,我们简单理解了泛型的含义。在使用泛型时,请注意其使用规则和限制,如下:

1、泛型的参数类型只能是类(class)类型,而不能是简单类型。

      比如,<int>是不可使用的。

2、可以声明多个泛型参数类型,比如<T, P,Q…>,同时还可以嵌套泛型,例如:<List<String>>

3、泛型的参数类型可以使用extends语句,例如<T extends superclass>。

4、泛型的参数类型可以使用super语句,例如< T super childclass>。

5、泛型还可以使用通配符,例如<? extends ArrayList>

 

五、 扩展

1、extends语句

使用extends语句将限制泛型参数的适用范围。例如:

<T extends collection> ,则表示该泛型参数的使用范围是所有实现了collection接口的calss。如果传入一个<String>则程序编译出错。

2、super语句

super语句的作用与extends一样,都是限制泛型参数的适用范围。区别在于,super是限制泛型参数只能是指定该class的上层父类。

例如<T super List>,表示该泛型参数只能是List和List的上层父类。

3、通配符

使用通配符的目的是为了解决泛型参数被限制死了不能动态根据实例来确定的缺点。

举个例子:public class SampleClass < T extends S> {…}

假如A,B,C,…Z这26个class都实现了S接口。我们使用时需要使用到这26个class类型的泛型参数。那实例化的时候怎么办呢?依次写下

SampleClass<A> a = new SampleClass();

SampleClass<B> a = new SampleClass();

SampleClass<Z> a = new SampleClass();

这显然很冗余,还不如使用Object而不使用泛型,呵呵,是吧?

别着急,咱们使用通配符,就OK了。

SampleClass<? Extends S> sc = new SampleClass();

 

只需要声明一个sc变量,很方便把!


本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/bluesmile979/archive/2009/03/10/3976905.aspx

JavaJava中一种强大的特性,允许编写类安全且可重用的代码,能创建灵活的组件处理不同数据类,同时保持代码的简洁性和可读性,对于编写高质量Java程序至关重要[^2]。 ### 基本概念 通俗理解,让类可以像方法的参数一样传递。例如`List<String>`中的`String`就是类参数,它告知编译器该`List`只能存放`String`类的对象[^3]。 ### 使用场景 - **类安全**:在没有时,需要强制类转换,容易导致`ClassCastException`,而使用能在编译时检查类安全,避免运行时异常。 - **代码复用**:不使用时,为不同类需要编写相似的代码,使用一套代码就可以适用于多种类。 - **代码清晰度**:没有时,需要查看文档或注释才能知道集合中存储的类,使用可直接从类声明了解集合中存储的类[^3]。 ### 使用方法 #### 类 在实例化类的时候指明的具体类。例如: ```java class Box<T> { private T t; public void set(T t) { this.t = t; } public T get() { return t; } } // 使用 Box<String> stringBox = new Box<>(); stringBox.set("Hello"); String value = stringBox.get(); ``` #### 方法 在调用方法的时候指明的具体类。示例如下: ```java public <T> T genericMethod(Class<T> tClass) throws InstantiationException, IllegalAccessException { T instance = tClass.newInstance(); return instance; } // 使用 try { String str = genericMethod(String.class); } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); } ``` ### 通配符 在代码中,问号`?`称为通配符,用来表示未知类。通配符可在多种情况下使用,如作为参数、字段或局部变量的类,有时也可作为返回类,但永远不会用作调用方法、创建类或超类实例的类参数。例如: ```java public static void printList(java.util.List<?> list) { for (Object element : list) { System.out.println(element); } } ``` ### 原理 Java是通过类擦除实现的。在编译时,编译器会把信息擦除,替换为原始类(如`List<String>`会被擦除为`List`),并在必要的地方插入类转换代码,以保证类安全。 ### 最佳实践 - **合理使用类和方法**:根据实际需求选择合适的形式,若类参数与类的整体相关,可使用类;若只与某个方法相关,则使用方法。 - **使用通配符提高灵活性**:当需要处理不同的集合时,合理使用通配符能提高代码的灵活性和复用性。 - **注意类擦除的影响**:由于类擦除,在运行时无法获取的具体类信息,编写代码时需考虑这一点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值