泛型类、泛型方法及泛型应用

泛型类、泛型方法及泛型应用

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

在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。

泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,以提高代码的重用率。

蓝桥软件学院的马洋老师讲解了泛型的相关内容:

规则限制:

1、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。

2、泛型的参数类型可以使用extends语句,例如<T extends superclass>。习惯上称为“有界类型”。

3、泛型的参数类型还可以是通配符类型。例如Class<?> classType = Class.forName("java.lang.String");

泛型还有接口、方法等等,内容很多,需要花费一番功夫才能理解掌握并熟练应用。在此给出我曾经了解泛型时候写出的两个例子(根据看的印象写的),实现同样的功能,一个使用了泛型,一个没有使用,通过对比,可以很快学会泛型的应用,学会这个基本上学会了泛型70%的内容。

例子一:使用了泛型


class Gen<T> {

private T ob; // 定义泛型成员变量

public Gen(T ob) {

this.ob = ob;

}

public T getOb() {

return ob;

}

public void setOb(T ob) {

this.ob = ob;

}

public void showType() {

System.out.println("T的实际类型是: " + ob.getClass().getName());

}

}

public class GenDemo {

public static void main(String[] args) {

// 定义泛型类Gen的一个Integer版本

Gen<Integer> intOb = new Gen<Integer>(88);

intOb.showType();

int i = intOb.getOb();

System.out.println("value= " + i);

System.out.println("----------------------------------");

// 定义泛型类Gen的一个String版本

Gen<String> strOb = new Gen<String>("Hello Gen!");

strOb.showType();

String s = strOb.getOb();

System.out.println("value= " + s);

}

}

例子二:没有使用泛型

?


class Gen2 {

private Object ob; // 定义一个通用类型成员

public Gen2(Object ob) {

this.ob = ob;

}

public Object getOb() {

return ob;

}

public void setOb(Object ob) {

this.ob = ob;

}

public void showTyep() {

System.out.println("T的实际类型是: " + ob.getClass().getName());

}

}

public class GenDemo2 {

public static void main(String[] args) {

// 定义类Gen2的一个Integer版本

Gen2 intOb = new Gen2(new Integer(88));

intOb.showTyep();

int i = (Integer) intOb.getOb();

System.out.println("value= " + i);

System.out.println("---------------------------------");

// 定义类Gen2的一个String版本

Gen2 strOb = new Gen2("Hello Gen!");

strOb.showTyep();

String s = (String) strOb.getOb();

System.out.println("value= " + s);

}

}

运行结果:

两个例子运行Demo结果是相同的,控制台输出结果如下:

T的实际类型是:

java.lang.Integer

value= 88

----------------------------------

T的实际类型是: java.lang.String

value= Hello Gen!

Process finished with exit code 0

看明白这个,以后基本的泛型应用和代码阅读就不成问题了。

泛型介绍:

一. 自定义泛型接口、泛型类和泛型方法

在泛型接口、泛型类和泛型方法的定义过程中,我们常见的如T、E、K、V等形式的参数常用于表示泛型形参,由于接收来自外部使用时候传入的类型实参。那么对于不同传入的类型实参,生成的相应对象实例的类型是不是一样的呢?

1 public class GenericTest {

2

3     public static void main(String[] args) {

4

5         Box<String> name = new Box<String>("corn");

6         Box<Integer> age = new Box<Integer>(712);

7

8         System.out.println("name class:" + name.getClass());      // com.qqyumidi.Box

9         System.out.println("age class:" + age.getClass());        // com.qqyumidi.Box

10         System.out.println(name.getClass() == age.getClass());    // true

11

12     }

13

14 }

究其原因,在于Java中的泛型这一概念提出的目的,导致其只是作用于代码编译阶段,【在编译过程中,对于正确检验泛型结果后,会将泛型的相关信息擦出,】也就是说,成功编译过后的class文件中是不包含任何泛型信息的。泛型信息不会进入到运行时阶段。

对此总结成一句话:泛型类型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型。

二.类型通配符

1.类似于Box<Number>和Box<Integer>是否可以看成具有父子关系的泛型类型呢?

public class GenericTest {

2

3     public static void main(String[] args) {

4

5         Box<Number> name = new Box<Number>(99);

6         Box<Integer> age = new Box<Integer>(712);

7

8         getData(name);

9

10         //The method getData(Box<Number>) in the type GenericTest is

11         //not applicable for the arguments (Box<Integer>)

12         getData(age);   // 1

13

14     }

15

16     public static void getData(Box<Number> data){

17         System.out.println("data :" + data.getData());

18     }

19

显然,通过提示信息,我们知道Box<Number>在逻辑上不能视为 Box<Integer>的父类。

本文由蓝桥软件学院(http://xueyuan.lanqiao.org)原创,转载请注明出处。

时间: 2025-01-02 14:00:45

泛型类、泛型方法及泛型应用的相关文章

泛型类定义和泛型方法以及泛型限定

1.泛型类定义的泛型,在整个类中有效.如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了. 2.为了让不同方法可以操作不同类型,而且类型还不确定.那么可以将泛型定义在方法上. 3.特殊之处: 静态方法不可以访问类上定义的泛型. 如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上. package tan; //定义泛型类(要操作的类型不确定) class Demo<T>{ public void show(T t){ System.out.print

转:C# 泛型编程之泛型类、泛型方法、泛型约束

C# 泛型编程之泛型类.泛型方法.泛型约束 分类: asp.net c#2012-08-07 17:36 5998人阅读 评论(0) 收藏 举报 c#编程classobject编译器struct 泛型方法 在C#2.0中,方法可以定义特定于其执行范围的泛型参数,如下所示: public class MyClass<T>    {        //指定MyMethod方法用以执行类型为X的参数        public void MyMethod<X>(X x)         

C# 泛型编程之泛型类、泛型方法、泛型约束

所谓泛型,即通过参数化类型来实现在同一份代码上操作多种数据类型. 泛型编程是一种编程范式,它利用"参数化类型"将类型抽象化,从而实现更为灵活的复用.在定义泛型类时,在对客户端代码能够在实例化类时,可以用类型参数的类型种类施加限制. 泛型方法 在C# 2.0中,方法可以定义特定于其执行范围的泛型参数,如下所示: public class MyClass<T> { //指定MyMethod方法用以执行类型为X的参数 public void MyMethod<X>(X

泛型接口、泛型委托、泛型方法、泛型约束

泛型接口 没有泛型接口,每次试图使用一个非泛型接口(如IComparable)来操纵一个值类型时,都会进行装箱,而且会丢失编译时的类型安全性.这会严重限制泛型类型的应用.所以,CLR提供了对泛型接口的支持.一个引用类型或值类型为了实现一个泛型接口,可以具体指定类型实参:另外,一个类型也可以保持类型实参的未指定状态来实现一个泛型接口.来看一些例子: 以下泛型接口定义是作为FCL的一部分发布的: public interface IEnumerable<T> : IDisposable, IEnu

Java泛型类泛型方法

使用泛型,在某些情况下可以有效减少代码量. Pair泛型类可以根据传入的参数类型进行相应的构造. minmax是泛型方法,不同数据类型的数组,也可以得到他们的min max值,需要注意的是传进去的T[]类类型必须是实现了Comparable方法的,否则无法调用compareTo()方法. 另外,泛型的类型必须是类类型,int, double, float这种是不行的,必须是Integer, Double, Float, String, StudentClass这种类类型的. /** 泛型类 *

java 泛型详解(普通泛型、 通配符、 泛型接口,泛型数组,泛型方法,泛型嵌套)

JDK1.5 令我们期待很久,可是当他发布的时候却更换版本号为5.0.这说明Java已经有大幅度的变化.本文将讲解JDK5.0支持的新功能-----Java的泛型. 1.Java泛型  其实Java的泛型就是创建一个用类型作为参数的类.就象我们写类的方法一样,方法是这样的method(String str1,String str2 ),方法中参数str1.str2的值是可变的.而泛型也是一样的,这样写class Java_Generics<K,V>,这里边的K和V就象方法中的参数str1和st

Java泛型的其他应用——泛型接口、泛型方法、泛型数组以及泛型的嵌套设置

学习目标 掌握泛型接口的使用 掌握泛型方法的定义的及使用 掌握泛型数组的使用 掌握泛型的嵌套设置 之前所有的操作都是在类中直接使用泛型操作的,那么,对于Java来说,也可以直接在接口中定义及使用泛型. 定义泛型接口 在JDK1.5之后,不仅仅可以声明泛型类,也可以声明泛型接口,声明泛型接口和声明泛型类的语法类似,也是在接口名称后面加上<T>,如下格式所示: [访问权限]  interface 接口名称<泛型标识>{} interface Info<T>{ // 在接口上

java泛型方法返回泛型结果

public class Test { static HashMap<String, String> sMap = new HashMap<String, String>(); public static void main(String[] args) { sMap.put("1", "23"); sMap.put("2", "ad"); sMap.put("3", "1

【c#基础】泛型

1:减少代码的选项可以是用Object类,也可以使用泛型 但是Object类进行类型传递不是类型安全的.泛型类使用泛型类型保证了类型安全. 泛型类 泛型方法 泛型接口 泛型优点: 1:性能 装箱和拆箱很容易使用,但性能损失比较大. 泛型的话在编译的时候就会动态生成我们定义他的类型,这样就不用进行装箱和拆箱. var list=new List<int>(); 上面这一句的话编译的时候就会编译成对应的int类型了,所以在运行的时候不用在进行装拆箱操作了. 2:类型安全 就是说你定义了一个List