当前位置:文档之家› 跟我学Java泛型技术及应用实例——Java泛型相关的应用技术

跟我学Java泛型技术及应用实例——Java泛型相关的应用技术

跟我学Java泛型技术及应用实例——Java泛型相关的应用技术
跟我学Java泛型技术及应用实例——Java泛型相关的应用技术

1.1跟我学Java泛型技术及应用实例——Java泛型相关的应用技术

1.1.1Java泛型相关的应用技术

1、什么是泛型----泛型的本质是参数化类型

(1)什么是泛型

泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

(2)在什么场合下需要应用泛型

如果一个类有一个或者多个类型的变量,那么这个类就是泛型类,这些类型变量是类的类型参数。

2、Java泛型的种类

Java的泛型主要有泛型类、泛型接口和泛型方法等,在Java语言中,将参数类型可以用在程序类、接口和方法的定义中,分别称为泛型类、泛型接口、泛型方法。

3、泛型类的代码示例

package com.bluedream.generics;

import java.util.Collection;

public class SomeGenericsDemo {

Collection oneCollection;

public void doSomeThing(E oneElement) {

oneCollection.add(oneElement);

/**

* 其它程序代码,在此省略...

*/

}

}

4、为什么要应用泛型

(1)泛型就好比Word中的模板

在Word的模板中,提供了基本的文档编辑内容,在定义Word模板时,对具体编辑哪种类型的文档是未知的。在Java中,泛型则提供了类、接口和方法、变量等的模板,泛型也可以看作是占位符,与定义Word模板时类似,定义泛型时的具体类型是未知的。

(2)Java语言引入泛型的好处是安全和简单

在Java SE 1.5之前,没有泛型的情况的下,通过对Object类型的对象引用来实现参数的“任意化”,“任意化”带来的缺点是需要在使用者的代码中要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型是可以预知的情况下进行的。如下为程序代码示例:package com.bluedream.generics;

import com.bluedream.swing.JToolBarTest;

public class SomeDigitClass{

public void doSomeThing(Object oneParameterObject) {

if(oneParameterObject instanceof Integer){

Integer targetParameterObject=(Integer)oneParameterObject;

}

else if(oneParameterObject instanceof Float){

Float targetParameterObject=(Float)oneParameterObject;

}

else{

Double targetParameterObject=(Double)oneParameterObject;

}

}

public static void main(String []args){

SomeDigitClass oneDigitClass=new SomeDigitClass();

oneDigitClass.doSomeThing("字符串类型的参数");

}

}

在上面的代码示例中,实际传递的参数的数据类型为字符串,但Java编译器并不认为参数的数据类型是非法,在如下示图中并没有给出编译错误。

而对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个很严重的安全隐患——在程序运行中查询了动态的错误。

(3)泛型的好处是在编译的时候就进行类型安全方面的检查

并且所有的强制类型转换都是自动和隐式的,以提高代码的可重用率。如下为运行时出现错误的示例代码:

package com.bluedream.generics;

import java.util.ArrayList;

import java.util.List;

public class SomeDigitClass{

public static void main(String []args){

List oneArrayListObject = new ArrayList();

oneArrayListObject.add("第1个正确的字符串参数");

oneArrayListObject.add("第2个正确的字符串参数");

oneArrayListObject.add(50);

for (int loopIndex = 0; loopIndex < oneArrayListObject.size(); loopIndex++) { String someOneParameter = (String) oneArrayListObject.get(loopIndex);

System.out.println("集合中的参数值为:" + someOneParameter);

}

}

}

在上面的示例代码中定义了一个List类型的集合对象oneArrayListObject,先向其中加入了两个字符串类型的值,随后加入一个Integer类型的值。这是完全允许的,因为此时的List集合的默认的类型为Object类型。

而在之后的循环中,由于忘记了之前在List集合中也加入了Integer类型的值或其他编码原因,很容易出现类似于下面示图中的错误。因为编译阶段正常,而运行时会出现“https://www.doczj.com/doc/9117403489.html,ng.ClassCastException”异常。因此,导致此类错误编码过程中不易发现。

由于在Java语言中的集合是不会“记住”添加在集合中的各个成员元素的数据类型,而当再次从集合中取出各个成员元素时,这些成员元素的编译类型都变成了Object类型,但其运行时类型任然为其本身类型。

因此,从集合中取出集合元素时需要人为的强制类型转化到具体的目标类型,且很容易出现类似的“https://www.doczj.com/doc/9117403489.html,ng.ClassCastException”异常。那么有没有什么办法可以使集合能够记住集合内的各个成员元素的数据类型,且能够达到只要编译时不出现问题,运行时也就不会出现“https://www.doczj.com/doc/9117403489.html,ng.ClassCastException”的异常呢?答案就是使用Java中的泛型技术。(4)应用泛型能够减少编码量并提高代码的通用性(简化代码结构、提高开发效率)

由于在Java集合中的List和ArrayList本身就是泛型定义,因此上面的程序代码应该要修改为如下的示例代码:

package com.bluedream.generics;

import java.util.ArrayList;

import java.util.List;

public class SomeDigitClass{

public static void main(String []args){

List oneArrayListObject = new ArrayList();

oneArrayListObject.add("第1个正确的字符串参数");

oneArrayListObject.add("第2个正确的字符串参数");

oneArrayListObject.add(50);

for (int loopIndex = 0; loopIndex < oneArrayListObject.size(); loopIndex++) { String someOneParameter = (String) oneArrayListObject.get(loopIndex);

System.out.println("集合中的参数值为:" + someOneParameter);

}

}

}

通过List直接限定了在此时的List集合中只能含有String类型的元素。此时,在应用时如果再给出错误类型的参数,编译系统将会及时进行语法检查并报告出对应的错误信息:

5、泛型在应用中的规则和限制

(1)泛型的类型参数只能是对“类”类型(包括自定义类),不能是简单的数据类型。

public void doSomeThing(E oneElement) {

/**

* 其它程序代码,在此省略...

*/

}

在上面的代码示例中的“E”不能为int、float等简单的数据类型,而必须为类或者接口类型。如果必须要使用基本的数据类型,则需要使用基本类型的包装类——如对于int类型马泽需要采用Integer类型。

(2)泛型的参数类型可以使用extends语句,例如 对此类型的泛型的参数类型习惯上称为“有界类型”,主要的目的是加以限定其范围。package com.bluedream.generics;

import java.util.Collection;

public class SomeGenericsDemo {

Collection oneCollection;

public void doSomeThing(E oneElement) {

oneCollection.add(oneElement);

/**

* 其它程序代码,在此省略...

*/

}

}

(3)泛型的参数类型还可以是通配符类型

例如代码示例中的:Class classType =

Class.forName("com.bluedream.generics.SomeGenericsDemo");

在使用通配符的泛型中需要使用“?”作为标记,它代表未知的类型。在程序代码执行完毕后的数据类型再最终确定。

package com.bluedream.generics;

public class SomeGenericsDemo {

public void doSomeThing(E oneElement) {

try {

Class classType =

Class.forName("com.bluedream.generics.SomeGenericsDemo");

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

}

(4)泛型类不可以继承Exception类,即泛型类不可以作为异常被抛出

package com.bluedream.generics;

import java.util.Collection;

public class SomeGenericsDemo extends Exception{

Collection oneCollection;

public void doSomeThing(E oneElement) {

oneCollection.add(oneElement);

/**

* 其它程序代码,在此省略...

*/

}

}

(5)不可以定义泛型数组、也不可以用泛型构造对象(即object = new T(); 是错误的),1)在static方法中不可以使用泛型

package com.bluedream.generics;

public class SomeGenericsDemo {

public static E getSingleInstance() {

}

}

2)泛型变量也不可以用static关键字来修饰

package com.bluedream.generics;

public class SomeGenericsDemo {

public static E singleInstance;

}

6、Java泛型的基本语法

(1)其定义的基本方式是通过某个类名后面的<>括号中的值指定

下面这一段示例代码说明如何定义泛型,其中用E代替在实际中将会使用到的类名(当然也可以使用其它别的名称,习惯上在这里使用大写的E,表示Collection的元素)。然后就可以采用该E来进行参数的定义。

通过在类名后面使用一对尖括号,中间放一个称为类型参数的“E”来定义泛型,该符号“E”其实是“类型占位符”或者称“类型参数”。

package com.bluedream.generics;

public class SomeGenericsDemo {

}

(2)代码示例1

package com.bluedream.generics;

import java.util.Collection;

public class SomeGenericsDemo{

Collection oneCollection;

public void doSomeThing(E oneElement) {

oneCollection.add(oneElement);

/**

* 其它程序代码,在此省略...

*/

}

}

(3)代码示例2

package com.bluedream.generics;

import java.util.List;

public class SomeGenericsDemo{

/**

* 下面的oneInteger现在为泛型变量

*/

SomeGenericsDemo oneInteger =null;

List someList=null;

/**

* 下面的方法现在为泛型方法

*/

public void doXXX(E someOneVal,E someTwoVal){ }

/**

* 下面的方法现在为泛型方法

*/

public E doYYY(){

return null;

}

public SomeGenericsDemo() {

oneInteger =new SomeGenericsDemo();

}

public static void main(String[] args) {

SomeGenericsDemo oneString=new SomeGenericsDemo();

}

}

7、Java 泛型与C++ 中的模板不同

(1)它很相似于C++中的类模板,但和类模板还是有一定的区别

表面上看起来,无论语法还是应用的环境(比如容器类),泛型类型(或者泛型)都类似于 C++ 中的模板。但是这种相似性仅限于表面:

1)Java 语言中的泛型基本上完全在编译器中实现,由编译器执行类型检查和类型推断,

然后生成普通的非泛型的字节码。

2)这种实现技术称为擦除(erasure)(编译器使用泛型类型信息保证类型安全,然后在

生成字节码之前将其清除;

3)最终在*.class文件中是不存在与泛型有关的描述内容。

(2)在Java虚拟机中是没有泛型类型的(所有对象都属于普通类)

无论何时定义一个泛型类型,相应的原始类型都会被自动提供。原始类型的名字就删去或者替代了类型参数的泛型类型的名字。类型变量被擦除时如果存在限定类型,则用其第一

个限定类型替换;如果不存在限定的类型变量则用Object类型替换。

1)用其第一个限定类型Comparable替换的示例:

package com.bluedream.generics;

import java.io.Serializable;

import java.util.List;

public class SomeGenericsDemo{ }

2)用其第一个限定类型Serializable替换的示例:

package com.bluedream.generics;

import java.io.Serializable;

import java.util.List;

public class SomeGenericsDemo{ }

3)无限定的类型变量时用Object替换的示例:

package com.bluedream.generics;

public class SomeGenericsDemo{

}

等同于如下的示例代码:

package com.bluedream.generics;

public class SomeGenericsDemo{

}

因为T是一个无限定的类型变量,所以简单地用Object替换。因此,要注意的是“泛型技术”还只是一种“编译期技术”。只能在编译期发挥作用,一旦软件完成编译,成为可执行代码,便失去了利用泛型的机会。

对于现在的多数应用而言,运行时的“多态”能力显得尤为重要。而现有的泛型无法在这个层面发挥作用。

8、泛型接口的代码示例

定义出一个泛型接口,并且在该接口中定义出一个泛型方法。

package com.bluedream.generics;

public interface SomeGenericsDemo{

public void doXXX(E oneVal);

public void doXXX(E oneVal,E twoVal);

public E doYYY();

public E doZZZ(E oneVal);

}

既然是接口,同样也要遵守接口的定义语法,在泛型接口中同样也不能对方法定义方法

体(方法的具体实现代码),如下的示例代码中的黑体方法是错误的:package com.bluedream.generics;

public interface SomeGenericsDemo{ public void doXXX(E oneVal){

}

public void doXXX(E oneVal,E twoVal);

public E doYYY();

public E doZZZ(E oneVal);

}

java泛型详解

java泛型详解 泛型(Generic type 或者generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。 可以在集合框架(Collection framework)中看到泛型的动机。例如,Map类允许您向一个Map添加任意类的对象,即使最常见的情况是在给定映射(map)中保存某个特定类型(比如String)的对象。 因为Map.get()被定义为返回Object,所以一般必须将Map.get()的结果强制类型转换为期望的类型,如下面的代码所示: Map m = new HashMap(); m.put("key", "blarg"); String s = (String) m.get("key"); 要让程序通过编译,必须将get()的结果强制类型转换为String,并且希望结果真的是一个String。但是有可能某人已经在该映射中保存了不是String的东西,这样的话,上面的代码将会抛出ClassCastException。 理想情况下,您可能会得出这样一个观点,即m是一个Map,它将String键映射到String值。这可以让您消除代码中的强制类型转换,同时获得一个附加的类型检查层,该检查层可以防止有人将错误类型的键或值保存在集合中。这就是泛型所做的工作。 泛型的好处 Java 语言中引入泛型是一个较大的功能增强。不仅语言、类型系统和编译器有了较大的变化,以支持泛型,而且类库也进行了大翻修,所以许多重要的类,比如集合框架,都已经成为泛型化的了。这带来了很多好处: · 类型安全。泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。 Java 程序中的一种流行技术是定义这样的集合,即它的元素或键是公共类型的,比如“Str ing列表”或者“String到String的映射”。通过在变量声明中捕获这一附加的类型信息,泛型允许编译器实施这些附加的类型约束。类型错误现在就可以在编译时被捕获了,而不是在运行时当作 ClassCastException展示出来。将类型检查从运行时挪到编译时有助于您更容易找到错误,并可提高程序的可靠性。

看一下Java泛型的设计

从零开始来看一下Java泛型的设计 泛型是Java中一个非常重要的知识点,在Java集合类框架中泛型被广泛应用。本文我们将从零开始来看一下Java泛型的设计,将会涉及到通配符处理,以及让人苦恼的类型擦除。 作者:ziwenxie来源:ziwenxie|2017-03-03 10:37 收藏 分享 引言 泛型是Java中一个非常重要的知识点,在Java集合类框架中泛型被广泛应用。本文我们将从零开始来看一下Java 泛型的设计,将会涉及到通配符处理,以及让人苦恼的类型擦除。 泛型基础 泛型类 我们首先定义一个简单的Box类: public class Box {

private String object; public void set(String object) { this.object = object; } public String get() { return object; } } 这是最常见的做法,这样做的一个坏处是Box里面现在只能装入String类型的元素,今后如果我们需要装入Integer 等其他类型的元素,还必须要另外重写一个Box,代码得不到复用,使用泛型可以很好的解决这个问题。 public class Box { // T stands for "Type" private T t; public void set(T t) { this.t = t; } public T get() { return t; } } 这样我们的Box类便可以得到复用,我们可以将T替换成任何我们想要的类型: Box integerBox = new Box(); Box doubleBox = new Box(); Box stringBox = new Box(); 泛型方法 看完了泛型类,接下来我们来了解一下泛型方法。声明一个泛型方法很简单,只要在返回类型前面加上一个类似的形式就行了: public class Util { public static boolean compare(Pair p1, Pair p2) { return p1.getKey().equals(p2.getKey()) && p1.getValue().equals(p2.getValue()); } }

java泛型

Java为什么要有泛型? 答: ①在没有泛型之前,一旦把一个对象添加到java集合中去,集合就会忘记对象的类型,把所有 的对象当成Object来处理.当程序从集合中取出对象后,就需要进行强制转换类型.这种类型转换不仅代码臃肿而且容易引起ClassCastException异常. ②增加了泛型支持后的集合,完全可以记住集合中的元素类型,并可以在编译时检查集合中 元素的类型,如果试图想集合中添加不满足类型要求的对象,编译器就会提示错误.增加泛型的集合,可以让代码更加简洁,程序更加健壮(java泛型可以保证如果程序在编译时候没有警告,运行时就不会产生ClassCastException). ③如果不设计泛型,那么集合中就可以装任何类型,所有可能引起异常。由于把对象丢进 集合时,集合失去了对象的状态信息,集合只知道它装的是Object类型元素,因此不仅麻烦还容易引起异常。 泛型 所谓泛型,就是允许在定义类、接口时指定类型形参,这个类型参数将在申明变量。创建对象时确定(既传入实际的类型参数,也可称为类型参数)。 代码欣赏:

上面三个接口定义的比较简单,除了尖括号中的内容—这就是泛型的实质:允许在定义接口、类时指定类型形参。类型形参在整个接口。类体内中可以当成类型使用,几乎所有可以使用其他普通类型的地方都可以使用这种类型参数。 泛型到底是什么?: 上面程序定义了一个带泛型声明的Apple类(先不要理会这个类型参数是否具有实际意义),实际使用Apple类的使用,必须给T传入实际类型。这样就生成了如Apple,Apple…等形式的逻辑子类(逻辑上不存在的子类)。 怎么使用泛型? 在开放中当我们需要一个父类,而父类中的方法或字段需要用到子类类型但是并不能确定到底要使用那一个子类类型或者遇到不知道子类具体类型,或者子类太多,不能写死一种子类时既可以给父类定义泛型,当实例化父类对象(或者使用父类对象创建子类对象时—多态)时再传入指定子类类型。

JAVA反射机制(内含大量实例)

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。其中LEAD/LEAD++ 、OpenC++ 、MetaXa和OpenJava等就是基于反射机制的语言。最近,反射机制也被应用到了视窗系统、操作系统和文件系统中。 反射本身并不是一个新概念,它可能会使我们联想到光学中的反射概念,尽管计算机科学赋予了反射概念新的含义,但是,从现象上来说,它们确实有某些相通之处,这些有助于我们的理解。在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。可以看出,同一般的反射概念相比,计算机科学领域的反射不单单指反射本身,还包括对反射结果所采取的措施。所有采用反射机制的系统(即反射系统)都希望使系统的实现更开放。可以说,实现了反射机制的系统都具有开放性,但具有开放性的系统并不一定采用了反射机制,开放性是反射系统的必要条件。一般来说,反射系统除了满足开放性条件外还必须满足原因连接(Causally-connected)。所谓原因连接是指对反射系统自描述的改变能够立即反映到系统底层的实

际状态和行为上的情况,反之亦然。开放性和原因连接是反射系统的两大基本要素。 Java中,反射是一种强大的工具。它使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接。反射允许我们在编写与执行时,使我们的程序代码能够接入装载到JVM中的类的内部信息,而不是源代码中选定的类协作的代码。这使反射成为构建灵活的应用的主要工具。但需注意的是:如果使用不当,反射的成本很高。 二、Java中的类反射: Reflection 是 Java 程序开发语言的特征之一,它允许运行中的Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性。Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。例如,Pascal、C 或者 C++ 中就没有办法在程序中获得函数定义相关的信息。 1.检测类: 1.1 reflection的工作机制 考虑下面这个简单的例子,让我们看看 reflection 是如何工作的。

16JAVA第六单元练习题 泛型与集合

6泛型与集合 6.1单项选择题 1.可实现有序对象的操作是?() A.HashMap B.HashSet C.TreeMap D.Stack 2.不是迭代器接口(Iterator)所定义的方法是()。 A.hasNext()B.next() C.remove()D.nextElement() 3.下面说法不正确的是() A.列表(List)、集合(Set)和映射(Map)都是java.util包中的接口。 B.List接口是可以包含重复元素的有序集合。 C.Set接口是不包含重复元素的集合。 D.Map接口将键映射到值,键可以重复,但每个键最多只能映射一个值。 4.下面那些方法不是接口Collection中已声明的方法() A.添加元素的add(Object obj)方法 B.删除元素的remove(Object obj)方法 C.得到元素个数的length()方法 D.返回迭代器的iterator()方法,迭代器用于元素遍历 5.下列关于容器的描述中,错误的是() A.容器是由若干个组建和容器组成的 B.容器是对图形界面中界面元素的一种管理 C.容器是一种对指定宽和高的矩形范围 D.容器都是可以独立的窗口 6.下列界面元素中,不是容器的是() A.List B.JFrame C.JDialog D.Panel 7.应用程序的main方法中有以下语句,则输出的结果是()。

Hashtable hashtable=new Hashtable(); hashtable.put("100","aaa"); hashtable.put("200","bbb"); hashtable.put("300","ccc"); System.out.println(hashtable.get("300").toString() +hashtable.get("200").toString() +hashtable.get("100").toString()); A)aaa B)bbb C)ccc D)cccbbbaaa 6.2判断题 1.Map接口是自Collection接口继承而来。(×) 2.集合Set是通过键-值对的方式来存储对象的。(×) 3.Integer i=(Integer.valueOf("926")).intValue();(√) 4.String s=(Double.valueOf("3.1415926")).toString();(√) 5.Integer I=Integer.parseInt("926");(√) 6.Arrays类主要对数组进行操作。(√) 7.在集合中元素类型必须是相同的。(√) 8.集合中可以包含相同的对象。(×) 9.枚举接口定义了具有删除功能的方法。(×) 6.3程序阅读题 1.阅读下面的程序,回答问题。 import java.util.*; public class T{ public static void main(String args[]){ Set set=new TreeSet(); set.add(new Integer(10)); set.add(new Integer(5)); set.add(new Integer(15)); set.add(new Integer(5)); set.add(new Integer(10)); System.out.println("size="+set.size()); Iterator it=set.iterator(); while(it.hasNext()){ System.out.print(it.next()+""); } }

Java泛型详解

Java 泛型 1 什么是泛型 (2) 2 泛型类跟接口及泛型方法 (3) 2.1 泛型类跟接口及继承 (3) 2.1.1泛型类 (3) 2.1.2继承 (3) 2.1.3接口 (3) 2.2 泛型方法 (3) 2.2.1 方法 (3) 2.2.2 类型推断 (4) 3 泛型实现原理 (5) 4 泛型数组 (6) 5边界 (7) 6通配符 (8) 7 泛型的问题及建议 (9) 7.1问题 (9) 7.2 建议 (9)

1 什么是泛型 从jdk1.5开始,Java中开始支持泛型了。泛型是一个很有用的编程工具,给我们带来了极大的灵活性。在看了《java核心编程》之后,我小有收获,写出来与大家分享。 所谓泛型,我的感觉就是,不用考虑对象的具体类型,就可以对对象进行一定的操作,对任何对象都能进行同样的操作。这就是灵活性之所在。但是,正是因为没有考虑对象的具体类型,因此一般情况下不可以使用对象自带的接口函数,因为不同的对象所携带的接口函数不一样,你使用了对象A的接口函数,万一别人将一个对象B传给泛型,那么程序就会出现错误,这就是泛型的局限性。所以说,泛型的最佳用途,就是用于实现容器类,实现一个通用的容器。该容器可以存储对象,也可以取出对象,而不用考虑对象的具体类型。因此,在学习泛型的时候,一定要了解这一点,你不能指望泛型是万能的,要充分考虑到泛型的局限性。下面我们来探讨一下泛型的原理以及高级应用。首先给出一个泛型类: public class Pair { public Pair() { first = null; second = null; } public Pair(T first, T second) { this.first = first; this.second = second; } public T getFirst() { return first; } public T getSecond() { return second; } public void setFirst(T newValue) { first = newValue; } public void setSecond(T newValue) { second = newValue; } private T first; private T second; } 我们看到,上述Pair类是一个容器类(我会多次强调,泛型天生就是为了容器类的方便实现),容纳了2个数据,但这2个数据类型是不确定的,用泛型T来表示。关于泛型类如何使用,那是最基本的内容,在此就不讨论了。

java泛型接口,泛型类泛型方法

泛型可提高代码的高扩展性和重用率. 1、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。 2、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。 3、泛型的类型参数可以有多个。 4、泛型的参数类型可以使用extends语句,例如。习惯上称为“有界类型”。 5、泛型的参数类型还可以是通配符类型。例如Class classType = Class.forName("https://www.doczj.com/doc/9117403489.html,ng.String"); 泛型可以用在接口,类方法,集合上面. 泛型接口: interface testGenerics{ T getT(T t); String assume(T t); } 泛型类:

public class GenericsFoo { private T x; public GenericsFoo(T x) { this.x = x; } public T getX() { return x; } public void setX(T x) { this.x = x; } } 使用来声明一个类型持有者名称,然后就可以把T当作一个类型代表来声明成员、参数和返回值类型。 当然T仅仅是个名字,这个名字可以自行定义。 泛型方法: 是否拥有泛型方法,与其所在的类是否泛型没有关系。要定义泛型方法,只需将泛型参数列表置于返回值前。如: public class ExampleA { public void f(T x) {

System.out.println(x.getClass().getName()); } 使用泛型方法时,不必指明参数类型,编译器会自己找出具体的类型。泛型方法除了定义不同,调用就像普通方法一样。 限制泛型的可用类型: 在上面的例子中,由于没有限制class GenericsFoo类型持有者T的范围,实际上这里的限定类型相当于Object,这和“Object泛型”实质是一样的。限制比如我们要限制T为集合接口类型。只需要这么做: class GenericsFoo,这样类中的泛型T 只能是Collection接口的实现类,传入非Collection接口编译会出错。 注意:这里的限定使用关键字extends,后面可以是类也可以是接口。但这里的extends已经不是继承的含义了,应该理解为T类型是实现Collection接口的类型,或者T是继承了XX类的类型。 下面继续对上面的例子改进,我只要实现了集合接口的类型: public class CollectionGenFoo { private T x; public CollectionGenFoo(T x) { this.x = x;

实验七:Java集合与泛型

实验七Java集合与泛型 一、实验目的 1)掌握集合的概念、体系结构、分类及使用场景 2)了解Set接口及主要实现类(HashSet、TreeSet) 3)了解List接口及主要实现类(ArrayList、LinkedList、Vector) 4)掌握ArrayList的使用 5)掌握ArrayList与Vector的区别 6)了解Map接口及主要实现类(HashMap、TreeMap、HashTable) 7)掌握HashMap的使用 8)掌握HashMap与HashTable的区别 二、实验环境 JDK1.6+Eclpise3.2 三、实验准备 1)复习课件中理论知识 2)练习课堂所讲的例子 四、实验内容 1、编写程序练习List集合的基本使用: 1) 创建一个只能容纳String对象名为names的ArrayList集合; 2)按顺序往集合中添加5个字符串对象:“张三”、“李四”、“王五”、“马六”、“赵七”; 3)对集合进行遍历,分别打印集合中的每个元素的位置与内容; 4)首先打印集合的大小,然后删除集合中的第3个元素,并显示删除元素的内容,然后再打印目前集合中第3个元素的内容,并再次打印集合的大小。 2、编写程序练习Map集合的基本使用: 1)创建一个只能值只能容纳String对象的person的HashMap集合; 2)往集合中添加5个“键-值”对象:id—>”1”、name—>”张三”、sex—>”男”、age—>”25”、love—>”爱学Java” 3)对集合进行遍历,分别打印集合中的每个元素的键与值; 4)首先打印集合的大小,然后删除集合中的键为age的元素,并显示删除元素的内容,并再次打印集合的大小。 五、验过程及结果 第1题调试结果如下图:

java泛型详解

Java 泛型详解 泛型是Java中一个非常重要的知识点,在Java集合类框架中泛型被广泛应用。本文我们将从零开始来看一下Java 泛型的设计,将会涉及到通配符处理,以及让人苦恼的类型擦除。 泛型基础 泛型类 我们首先定义一个简单的Box类: public class Box { private String object; public void set(String object) { this.object = object; } public String get() { return object; }}这是最常见的做法,这样做的一个坏处是Box里面现在只能装入String类型的元素,今后如果我们需要装入Integer等其他类型的元素,还必须要另外重写一个Box,代码得不到复用,使用泛型可以很好的解决这个问题。 public class Box { // T stands for 'Type' private T t; public void set(T t) { this.t = t; } public T get() { return t; }} 这样我们的Box类便可以得到复用,我们可以将T替换成任何我们想要的类型: Box integerBox = new Box();Box doubleBox = new

Box();Box stringBox = new Box(); 泛型方法 看完了泛型类,接下来我们来了解一下泛型方法。声明一个泛型方法很简单,只要在返回类型前面加上一个类似的形式就行了: public class Util { public static boolean compare(Pair p1, Pair p2) { return p1.getKey().equals(p2.getKey()) && p1.getValue().equals(p2.getValue()); }}public class Pair { private K key; private V value; public Pair(K key, V value) { this.key = key; this.value = value; } public void setKey(K key) { this.key = key; } public void setValue(V value) { this.value = value; } public K getKey() { return key; } public V getValue() { return value; }} 我们可以像下面这样去调用泛型方法: Pair p1 = new Pair(1, 'apple');Pair p2 = new Pair(2, 'pear');boolean same = https://www.doczj.com/doc/9117403489.html,pare(p1, p2); 或者在Java1.7/1.8利用type inference,让Java自动推导出相应的类型参数: Pair p1 = new Pair(1, 'apple');Pair p2 = new Pair(2, 'pear');boolean same = https://www.doczj.com/doc/9117403489.html,pare(p1, p2);

一个例子让你了解Java反射机制

一个例子让你了解Java反射机制 JAVA反射机制: 通俗地说,反射机制就是可以把一个类,类的成员(函数,属性),当成一个对象来操作,希望读者能理解,也就是说,类,类的成员,我们在运行的时候还可以动态地去操作他们. 理论的东东太多也没用,下面我们看看实践 Demo ~ Demo: 1.package cn.lee.demo; 2. 3.import https://www.doczj.com/doc/9117403489.html,ng.reflect.Constructor; 4.import https://www.doczj.com/doc/9117403489.html,ng.reflect.Field; 5.import https://www.doczj.com/doc/9117403489.html,ng.reflect.InvocationTargetException; 6.import https://www.doczj.com/doc/9117403489.html,ng.reflect.Method; 7.import https://www.doczj.com/doc/9117403489.html,ng.reflect.Modifier; 8.import https://www.doczj.com/doc/9117403489.html,ng.reflect.TypeVariable; 9. 10.public class Main { 11. /** 12. * 为了看清楚Java反射部分代码,所有异常我都最后抛出来给虚拟机处 理! 13. * @param args 14. * @throws ClassNotFoundException 15. * @throws InstantiationException 16. * @throws IllegalAccessException 17. * @throws InvocationTargetException 18. * @throws IllegalArgumentException 19. * @throws NoSuchFieldException 20. * @throws SecurityException 21. * @throws NoSuchMethodException 22. */

JavaEE考试题

一、填空题 1.企业级应用程序通常应具备快速适应性、分布式、高安全性、可扩展性和集成 化等特性。P(6) 2.两层体系结构由客户层和服务器层构成,即所谓的C/S 模式。P(7) 3.三层体系结构通常包括客户层、服务器层和应用服务器层三个层 次。P(7) 4.典型Java EE 应用包括:客户层、表示层(Web层)、业务逻辑层和企业信息 系统层四个层次。P(8) 5.Java EE技术框架大致包括组件技术、服务技术和通信技术三个 部分。P(11) 6.Java EE组件主要包括客户端组件、Web组件和EJB组件三大类。 P(10) 7.按打包粒度从小至大的顺序,Java归档包的类型分别是JAR 、WAR 和 EAR 。(PPT) 8.程序错误可分为语法错、语义错和逻辑错三类。P(20) 9.JSP指令元素主要包括include 、page 和taglib 三个。P(34) 10.include指令的基本语法为<%@ include file=”URL” %> 。P(34) 11.taglib指令的基本语法为<%@ taglib uri=”taglibURI” prefix=”pre” %> 。P(35) 12.JSP参数标记的基本语法为 P(39) 13.读取request单值参数的方法是getParameter() ,读取多值参数的方法是 getParameterValues()。获取所有参数名称的方法是getParameterNames() 。P(44) 14.request作用范围变量可以通过setAttribute() 和getAttribute() 方法设置和读取变量的数据。P(45) 15.调用response对象的addCookie(Cookie cookie)方法可将一个 Cookie对象传回客户端保存。P(48) 16.调用request 对象的getCookies() 方法可以读取保存在客户端的所有 Cookie对象。P(48) 17.在web.xml文件中定义Web应用初始化参数的标记是 和子标记。(源于PPT)

深入理解Java反射机制汇总

深入理解Java反射机制 本文较为详细的分析了Java反射机制。分享给大家供大家参考,具体如下: 一、预先需要掌握的知识(java虚拟机) java虚拟机的方法区: java虚拟机有一个运行时数据区,这个数据区又被分为方法区,堆区和栈区,我们这里需要了解的主要是方法区。方法区的主要作用是存储被装载的类的类型信息,当java虚拟机装载某个类型的时候,需要类装载器定位相应的class文件,然后将其读入到java虚拟机中,紧接着虚拟机提取class 中的类型信息,将这些信息存储到方法区中。这些信息主要包括: 1、这个类型的全限定名 2、这个类型的直接超类的全限定名 3、这个类型是类类型还是接口类型 4、这个类型的访问修饰符 5、任何直接超接口的全限定名的有序列表 6、该类型的常量池 7、字段信息 8、方法信息 9、除了常量以外的所有类变量 10、一个到class类的引用 等等(读者可以参考《深入java虚拟机》这本书的叙述) Class类: Class类是一个非常重要的java基础类,每当装载一个新的类型的时候,java虚拟机都会在java堆中创建一个对应于新类型的Class实例,该实例就代表此类型,通过该Class实例我们就可以访问该类型的基本信息。上面说到在方法区中会存储某个被装载类的类型信息,我们就可以通过Class实例来访问这些信息。比如,对于上面说到的信息Class中都有对应的方法,如下:

1、getName();这个类型的全限定名 2、getSuperClass();这个类型的直接超类的全限定名 3、isInterface();这个类型是类类型还是接口类型 4、getTypeParamters();这个类型的访问修饰符 5、getInterfaces();任何直接超接口的全限定名的有序列表 6、getFields();字段信息 7、getMethods();方法信息 等等(读者可以自己参看jdk帮助文档,得到更多的信息) 二、java反射详解 反射的概念:所谓的反射就是java语言在运行时拥有一项自观的能力,反射使您的程序代码能够得到装载到JVM中的类的内部信息,允许您执行程序时才得到需要类的内部信息,而不是在编写代码的时候就必须要知道所需类的内部信息,这使反射成为构建灵活的应用的主要工具。 反射的常用类和函数:Java反射机制的实现要借助于4个类:Class,Constructor,Field,Method;其中class代表的是类对象,Constructor-类的构造器对象,Field-类的属性对象,Method -类的方法对象,通过这四个对象我们可以粗略的看到一个类的各个组成部分。其中最核心的就是Class类,它是实现反射的基础,它包含的方法我们在第一部分已经进行了基本的阐述。应用反射时我们最关心的一般是一个类的构造器、属性和方法,下面我们主要介绍Class 类中针对这三个元素的方法: 1、得到构造器的方法 Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数,Constructor[] getConstructors() -- 获得类的所有公共构造函数 Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别无关) Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关) 2、获得字段信息的方法

Java中类反射机制基本原理

Java中的类反射机制 一、反射的概念 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。其中LEAD/LEAD++ 、Open C++ 、Meta Xa和Open Java等就是基于反射机制的语言。最近,反射机制也被应用到了视窗系统、操作系统和文件系统中。 反射本身并不是一个新概念,它可能会使我们联想到光学中的反射概念,尽管计算机科学赋予了反射概念新的含义,但是,从现象上来说,它们确实有某些相通之处,这些有助于我们的理解。在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。可以看出,同一般的反射概念相比,计算机科学领域的反射不单单指反射本身,还包括对反射结果所采取的措施。所有采用反射机制的系统(即反射系统)都希望使系统的实现更开放。可以说,实现了反射机制的系统都具有开放性,但具有开放性的系统并不一定采用了反射机制,开放性是反射系统的必要条件。一般来说,反射系统除了满足开放性条件外还必须满足原因连接(Causally-connected)。所谓原因连接是指对反射系统自描述的改变能够立即反映到系统底层的实际状态和行为上的情况,反之亦然。开放性和原因连接是反射系统的两大基本要素。 Java中,反射是一种强大的工具。它使您能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接。反射允许我们在编写与执行时,使我们的程序代码能够接入装载到JVM中的类的内部信息,而不是源代码中选定的类协作的代码。这使反射成为构建灵活的应用的主要工具。但需注意的是:如果使用不当,反射的成本很高。 二、Java类反射 Reflection 是Java 程序开发语言的特征之一,它允许运行中的Java 程序对自身进行检查,或者说“自审”,并能直接操作程序的内部属性。Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。例如,Pascal、C 或者C++ 中就没有办法在程序中获得函数定义相关的信息。 1.检测类 1.1 reflection的工作机制 考虑下面这个简单的例子,让我们看看reflection 是如何工作的。 import https://www.doczj.com/doc/9117403489.html,ng.reflect.*; public class DumpMethods { public static void main(String args[]) { try { Class c = Class.forName(args[0]); Method m[] = c.getDeclaredMethods(); for (int i = 0; i < m.length; i++) System.out.println(m[i].toString()); } catch (Throwable e) { System.err.println(e); }

java反射机制详解与应用

java有着一个非常突出的动态相关机制:Reflection。这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods1。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。 这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等等)、superclass(例如Object)、实现之interfaces (例如Cloneable),也包括fields和methods的所有信息,并可于运行时改变fields内容或唤起methods。 目前好多框架都会用到java的反射机制。比如struts2,sping,hibernate。 如果我们不用struts2,自己写一个类似的功能也是可以实现的,比如浏览器通过HTTP发送数据,而这些数据都是字符串,我们接受到这些字符串时,可以通过反射去构造一个对象(通过拦截器做成框架的功能),这样就可以用对象的get和set方法了,而不用原始的getPeremter 方法。事实上,在struts2出来之前,我们又不想用struts1的ActionForm就做过这样项目。 一、Class object 的产生方式有以下几种。 1、运用getClass() 注:每个class 都有此函数 String str = "abc"; Class c1 = str.getClass(); 2、运用static method Class.forName()(最常被使用) Class c1 = Class.forName ("https://www.doczj.com/doc/9117403489.html,ng.String"); Class c2 = Class.forName ("java.awt.Button"); 3、运用.class 语法 Class c1 = String.class; Class c2 = java.awt.Button.class; 4、运用primitive wrapper classes的TYPE 语法 Class c1 = Integer.TYPE; Class c2 = Long.TYPE; 二、Java类反射中的主要方法 对于以下三类组件中的任何一类来说-- 构造函数、字段和方法-- https://www.doczj.com/doc/9117403489.html,ng.Class 提供四种

java中的泛型

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和str2,也是可变。下面看看例子: 正确输出:value 这只是个例子(Java中集合框架都泛型化了,这里费了2遍事.),不过看看是不是创建一个用类型作为参数的类,参数是K,V,传入的“值”是String类型。这个类他没有特定的待处理型别,以前我们定义好了一个类,在输入输入参数有所固定,是什么型别的有要求,但是现在编写程序,完全可以不制定参数的类型,具体用的时候来确定,增加了程序的通用性,像是一个模板。 呵呵,类似C++的模板(类似)。 1.1. 泛型通配符 下面我们先看看这些程序:

看看这个方法有没有异议,这个方法会通过编译的,假如你传入String,就是这样List <String>。 接着我们调用它,问题就出现了,我们将一个List<String>当作List传给了方法,JVM会给我们一个警告,说这个破坏了类型安全,因为从List中返回的都是Object类型的,而让我们再看看下面的方法。 因为这里的List<String>不是List<Object>的子类,不是String与Object的关系,就是说List<String>不隶属于list<Object>,他们不是继承关系,所以是不行的,这里的extends是表示限制的。 类型通配符是很神奇的,List<?>这个你能为他做什么呢?怎么都是“?”,它似乎不确定,他总不能返回一个?作为类型的数据吧,是啊他是不会返回一个“?”来问程序员的?JVM会做简单的思考的,看看代码吧,更直观些。 这段代码没问题的,l1.get(0)将返回一个Object。 1.2. 编写泛型类要注意: 1) 在定义一个泛型类的时候,在“<>”之间定义形式类型参数,例如:“class TestGen <K,V>”,其中“K” , “V”不代表值,而是表示类型。 2) 实例化泛型对象的时候,一定要在类名后面指定类型参数的值(类型),一共要有两次书写。例如: TestGen<String,String> t=new TestGen<String,String>();

Java泛型使用详细分析

Java 泛型使用详细分析 、泛型的简介 1、为什么要使用泛型? 一般使用在集合上,比如现在把一个字符串类型的值放入到集合里面,这个时候,这个值放到集合之后,失去本身的类型,只能是object 类型。这时,如果想要对这个值进行类型转换,很容易出现类型转换错误,怎么解决这个问题,可以使用泛型来解决。 2、在泛型里面写是一个对象,String 不能写基本的数据类型比如int, 要写基本的数据类型对应的包装类 、在集合上如何使用泛型 - 常用集合list set map - 泛型语法:集合 比如list // 泛型在list 上的使用 @Test

public void testList() { List list = new ArrayList(); list.add("aaa"); list.add("bbb"); list.add("ccc"); //for 循环 for (int i = 1;i it = list.iterator(); while (it.hasNext()){ System.out.println(it.next()); } // 泛型在set 上的使用 @Test public void testSet() {

Java反射访问私有变量和私有方法

Java反射访问私有变量和私有方法 引言 对于软件开发人员来说,单元测试是一项必不可少的工作。它既可以验证程序的有效性,又可以在程序出现BUG 的时候,帮助开发人员快速的定位问题所在。但是,在写单元测试的过程中,开发人员经常要访问类的一些非公有的成员变量或方法,这给测试工作带来了很大的困扰。本文总结了访问类的非公有成员变量或方法的四种途径,以方便测试人员在需要访问类非公有成员变量或方法时进行选择。 尽管有很多经验丰富的程序员认为不应该提倡访问类的私有成员变量或方法,因为这样做违反了Java 语言封装性的基本规则。然而,在实际测试中被测试的对象千奇百怪,为了有效快速的进行单元测试,有时我们不得不违反一些这样或那样的规则。本文只讨论如何访问类的非公有成员变量或方法,至于是否应该在开发测试中这样做,则留给读者自己根据实际情况去判断和选择。 方法一:修改访问权限修饰符 先介绍最简单也是最直接的方法,就是利用Java 语言自身的特性,达到访问非公有成员的目的。说白了就是直接将private 和protected 关键字改为public 或者直接删除。我们建议直接删除,因为在Java 语言定义中,缺省访问修饰符是包可见的。这样做之后,我们可以另建一个源码目录——test 目录(多数IDE 支持这么做,如Eclipse 和JBuilder),然后将测试类放到test 目录相同包下,从而达到访问待测类的成员变量和方法的目的。此时,在其它包的代码依然不能访问这些变量或方法,在一定程度上保障了程序的封装性。 下面的代码示例展示了这一方法。 清单1. 原始待测类 A 代码 public class A { private String name = null; private void calculate() { } }

相关主题
相关文档 最新文档