`
喻红叶
  • 浏览: 40811 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
社区版块
存档分类
最新评论

泛型-Java泛型基础

 
阅读更多

面向对象相对于面向过程而言,是软件领域的一个重大进步。面向对象的多态特性,使得系统具有了较好的扩展性,通常我们使用父类来代替具体的类型,在实际运行时,却可以使用子类的对象。Java又更进了一步,提倡面向接口的编程,我们指定接口而不是具体的实现类。这样的约束有时候还是太强,我们希望编写更通用的代码,使代码能够用运行于“某种不具体的类型”,而不是具体的接口或类。

泛型的概念

假设我们要实现一个类,这个类持有一个属性,为了灵活,我们希望这个属性可以是任何类型,如果这样的话,这个属性就应该定义为Object类型的,其实现代码如下:

public class Holder {
    private Object obj;

    public void setObj(Object obj) {
        this.obj = obj;
    }

    public Object getObj() {
        return obj;
    }
}
在实际使用的时候,不管传递进来的参数是什么类型,在Holder类里都被向上转型为Object类型了;在希望获得持有的属性时,也仅仅能得到Object类型,必须要使用类型转换
Holder holder = new Holder();
holder.setObj("cxy");
//显式的类型转换
String name = (String)holder.getObj();
我们可以看到,get()返回的是Object类型,但其实我们希望得到更具体的类型,这个时候就要使用类型转换。问题是,类型转换的任务需要有程序员来完成,这意味着程序要需要知道Holder实际持有的是什么类型的。如果在类型转换时发生了错误,必须要等到运行期才能发现。
holder.set(new Integer(1));
//错误的类型转换
String name = (String)holder.get();
我们希望错误发现的越早越好。泛型就是用来保证类型的正确性的,在定义类时,使用一个占位符,代表类型信息,通常使用T来表示。上面的代码如果使用泛型来写:
public class Holder<T> {
    private T obj;
    public void set(T t) {
        obj = t;
    }

    public T get() {
        return obj;
    }
}
在使用的时候,只需要用实际的类型来代替T,编译器会确保传递和获得时的类型正确性。如下面的代码所示:
//只能持有String类型
Holder<String> holder = new Holder<String>();
holder.set("cxy");
//编译器会确保返回的是String类型
String name = holder.get();
//如果试图传入非String类型的参数,编译无法通过
//holder.set(new Integer(1));
就是这么简单,类型的正确性由编译器来处理,但其实Java中的泛型远比想象中的要复杂,上面只是泛型最简单的用法,泛型出了可以和普通类配合使用之外,还可以和接口、内部类一起使用,可以写一个没有实际意义的代码来演示一下:
//泛型接口
public interface GenericIn<T> {
    public void f();
}

//泛型匿名内部类
public class Outer<T> {
    public GenericIn<T> getGeneric() {
        return new GenericInt<T>() {
               public void f() {
                   do something
               }
        };
    }
}
泛型方法

泛型类在定义时使用一个占位符来表示类型,这个类型只有在具体构造该类的实例时才会知道,所以static方法和static字段都不能使用泛型类的类型参数,如果static想要拥有泛型能力,必须要借助于其他的机制。还有,有时候我们仅仅希望某个方法拥有泛型能力,而不是整个类,这样更加方便灵活,不用为了局部的泛型需要,而必须要在所有使用该的地方都使用泛型。出于以上两个原因,泛型方法就被提出来了。泛型方法的定义很简单,就是把类型参数放到方法的返回值之前:

public <T> void f();
public <T> T f(T t);
这样在方法f内部就可以使用类型T了。泛型方法是独立于泛型类而产生变化的,不是泛型类也可以拥有泛型方法;泛型方法可以使用额外的类型信息:
public class Generic<T> {
   //泛型方法使用额外的类型信息
   public <K> K f(K k) {
       return k; 
   }
}
在创建泛型类时必须要显式的指定类型信息,而在使用泛型方法时则不用,编译器会自动找出具体的类型,这称为类型推断(type argument inference)。比如
//编译器会自动推断出类型是String
String value = xxx.f("value");
但是类型推断只有在赋值时有效,在其他的时候,类型参数并不起作用,有如下代码:
public static <K,V> Map<K,V> map() {
	return new HashMap<K,V>();
}

static void f(Map<String, String> map){}
如果这样调用是通不过的:
f(map());
因为不是赋值操作,所以编译器会认为map()返回的是Map<Object,Object>。这个时候可以使用显式的类型说明来解决此问题,显式的类型说明就是在方法调用者和方法之间指定类型信息,如果是在类内部调用实例方法,需要使用this,如果是类方法,需要使用类名,其形式如下:
f(ClassName.<Map<String,String>>map());

以上只是泛型的基本用法,Java的泛型远比想象的要复杂,Java的泛型并不是真正的泛型,而是使用擦除来实现的,泛型所有的动作都是由编译器来完成的,在实际运行时,虚拟机根本不知道泛型的存在,具体内容可以参考《泛型-擦除实现的Java泛型》

转载请注明:喻红叶《泛型-Java泛型基础》

分享到:
评论

相关推荐

    Java 第二阶段提升编程能力【泛型】---- 代码

    Java 第二阶段提升编程能力【泛型】---- 代码 Java 第二阶段提升编程能力【泛型】---- 代码 Java 第二阶段提升编程能力【泛型】---- 代码 Java 第二阶段提升编程能力【泛型】---- 代码 Java 第二阶段提升编程能力...

    全面总结Java泛型--实例

    标题与描述均提到了“全面总结Java泛型--实例”,这表明文章旨在深入解析Java泛型的概念,并通过具体示例来展示其应用。Java泛型是Java编程语言的一个强大特性,它允许在编译时检查类型安全,并且所有的强制转换都是...

    java-泛型-面试题.docx

    java-泛型-面试题.docx

    29-API-集合框架-泛型-使用_java_

    通过学习和掌握Java泛型,开发者能够编写出更健壮、类型安全的代码,减少类型转换错误,提升代码质量。这个视频教程"29-API-集合框架-泛型-使用"应该会深入浅出地讲解这些概念,对于想要提升Java编程技能的初学者或...

    Generic_2(泛型类-泛型方法-泛型接口-泛型限定(上限)

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

    java中的泛型-详细

    总的来说,Java泛型提供了一种强大的工具,让开发者能够编写更加安全、灵活且可复用的代码。它简化了类型转换,增强了类型检查,并通过类型擦除保持了与现有Java代码的兼容性。理解和熟练运用泛型是每个Java开发者的...

    JAVA-泛型课件-泛型课件

    泛型是Java语言的一个重要特性,首次出现在Java SE 1.5版本中。它的引入主要是为了解决在集合操作中类型安全性的问题,并通过引入参数化类型的概念,提高了代码的复用性与可读性。 ### 泛型概念 泛型,即参数化...

    补充知识:泛型1---马克-to-win java视频

    补充知识:泛型1---马克-to-win java视频的详细描述与介绍

    基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip

    基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip 基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip 基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码....

    【Java基础】泛型方法 - 右撇子 - 博客频道 - CSDN.NET

    【Java基础】泛型方法 - 右撇子 - 博客频道 - CSDN.NET

    关于java基础的泛型的练习

    Java泛型是Java SE 5.0引入的一个重要特性,它极大地增强了代码的类型安全性和可读性。泛型在编程中的应用广泛,特别是在集合框架中,使得我们可以在编译时就检查类型,避免了不必要的类型转换,并且提高了代码的...

    很好的Java泛型的总结

    Java泛型机制详解 Java泛型是Java语言中的一种机制,用于在编译期检查类型安全。Java泛型的出现解决了Java早期版本中类型安全检查的缺陷。Java泛型的好处是可以在编译期检查类型安全,避免了运行时的...

    Java泛型_Java中的泛型结构_

    Java泛型是Java编程语言中一个强大的特性,它允许在定义类、接口和方法时使用类型参数,从而实现参数化类型。泛型的主要目标是提高代码的类型安全性和重用性,减少类型转换的麻烦,并在编译时捕获可能的类型错误。...

    后端研究-泛型机制在Apla-Java程序生成系统中实现的方法研究.pdf

    后端研究-泛型机制在Apla-Java程序生成系统中实现的方法研究 泛型机制是一种高级编程语言的重要机制,它可以提高软件的可靠性和生产效率。近年来,软件行业对泛型机制的研究和实现达到了新的高度。本文将研究在Apla...

    补充知识:泛型2---马克-to-win java视频

    补充知识2 ---马克-to-win java视频泛型的详细描述与介绍

    大学课程讲义-Java基础-泛型.docx

    Java泛型是Java编程语言中的一种特性,它允许在数据结构(如集合)中存储特定类型的元素,从而提供了编译时的类型安全性和更清晰的代码。泛型引入的主要目标是消除强制类型转换的需要,减少类型转换带来的潜在错误,...

    Java 实现泛型List

    Java 实现泛型List的源码,基本实现了List接口的全部所有方法。欢迎大家发表自己的观点和建议。

Global site tag (gtag.js) - Google Analytics