Java按位异或运算符

Java按位异或运算符 按位异或运算符 两个操作数中,如果两个相应位相同,则结果为0,否则为1 即: 0^0=0, 1^0=1, 0^1=1, 1^1=0 例如: 00101010^00010111=00111101 1)如果需使用一个整数的某些特定的位翻转,可使用另一个 相应位为1的操作数与原来的整数进行按位异或操作实现。 下面的例子对整数变量 ii的第四位翻转 int revertFouth=ii^8; 其余位则没有变化 通过按位异或运算可以实现两个值的交换。而不使用临 时变量。例如交换两个整数a,b的值可通过下列语句实现: int a=15,b=24; //a的最右边8位为00001111,b的最右边8位为00011000 //a和b其余位为0,下同 a=a^b; //a的最右边8位为00010111,a=23 b=b^a; //b的最右边8位为00001111,b=15 a=a^b; //a的最右边8位为00011000,a=24 *位逻辑运算表达式返回两个操作数中数据长度较长的数据 类型 其中较小的左侧将被填满,若为整数,则填满0, 若为负数,则左侧填满1 首先复习一下异或运算 (^) 的性质: 它满足交换律、结合律。 此处有一个经典的运用: 现在有一万 (1-10000) 的个数,从中拿掉一个数,问怎么才能找出拿掉的数? 设 最初的数组是 A, 拿掉 x 之后的数组是 B, xor() 是对数组内所有元素做异或,则有: xor(A) == xor(B) ^ x Fake代码 xor(A) == xor(B) ^ x 所以: xor(B) ^ xor(A) == xor(B) ^ xor(B) ^ x == 0 ^ x == x ...

2011-12-28 · 1 min · 123 words · -

JDO

JDO JDO(Java Data Object )是Java对象持久化的新的规范,也是一个用于存取某种数据仓库中的对象的标准化API。JDO提供了透明的对象存储,因此对开发人员来说,存储数据对象完全不需要额外的代码 (如JDBC API的使用) 。这些繁琐的例行工作已经转移到JDO产品提供商身上,使开发人员解脱出来,从而集中时间和精力在业务逻辑上。另外,JDO很灵活,因为它可以在任何数据底层上运行。JDBC只是面向关系数据库 (RDBMS) JDO更通用,提供到任何数据底层的存储功能,比如关系数据库、文件、XML以及对象数据库 (ODBMS) 等等,使得应用可移植性更强。 应用程序的开发人员通过访问JDO Instance , 达到访问JDO Instance 所代表的数据对象,包括:ERP,数据库系统等.使数据的存储介质对于应用的开发人员完全透明. JDO最早是由Sun召集众多的O/R Mapping开发团队集中起来共同提出的,首先是通过会议确定了JDO需要包括的内容,然后正式提出一个Java规范请求 (JSR-12) ,正式开始了JDO规范的制定。下面是主要的进展里程碑。 JSR #000012 approved in July 1999 1999-8组建的专家小组: 包括Sun、Apple、BEA、IBM、Oracle、SAP、WebGain等 2000-5 完成公开评论草案 2000-6 在JavaOne上引入 2001-3 最终草案0.93 2001-5 最终草案0.96公布 2001-6 在JavaOne上启动 2001-11 最终草案0.98 2002-4 1.0版正式公布 2002-8 1.0.1修正版 2003-8 2.0规范启动

2011-12-27 · 1 min · 48 words · -

java generic, 泛型

java generic, 泛型 泛型, generic 泛型是jdk5引入的类型机制,本质是将类型参数化(是早在1999年就制定的jsr14的实现) 也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是安全简单。 泛型解决了几个问题: 1 可读性,从字面上就可以判断集合中的内容类型; 2 类型检查,避免插入非法类型。 3 获取数据时不在需要强制类型转换。 在Java SE 1.5之前,没有泛型的情况的下,通过对类型(Object)的引用来实现参数的"任意化",“任意化"带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。 泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。 规则和限制 泛型的类型参数只能是类类型 (包括自定义类) ,不能是简单类型。 同一种泛型可以对应多个版本 (因为参数类型是不确定的) ,不同版本的泛型类实例是不兼容的。 泛型的类型参数可以有多个。 泛型的参数类型可以使用extends语句,例如。习惯上称为"有界类型”。 泛型的参数类型还可以是通配符类型。例如Class classType = Class.forName(“java.lang.String”); 泛型还有接口、方法等等,内容很多,需要花费一番功夫才能理解掌握并熟练应用。在此给出我曾经了解泛型时候写出的两个例子 (根据看的印象写的) ,实现同样的功能,一个使用了泛型,一个没有使用,通过对比,可以很快学会泛型的应用,学会这个基本上学会了泛型70%的内容。 例子一: 使用了泛型 package com.wiloon.test.generics; 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); } } 例子二: 没有使用泛型 ...

2011-12-26 · 11 min · 2182 words · -

Annotation/注解

Annotation/注解 annotation http://www.cnblogs.com/mandroid/archive/2011/07/18/2109829.html annotation 是Java5开始引入的新特征。中文名称一般叫注解。它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。 更通俗的意思是为程序的元素(类、方法、成员变量)加上更直观更明了的说明,这些说明信息是与程序的业务逻辑无关,并且是供指定的工具或框架使用的。 annotation 像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。 Annotation其实是一种接口。通过Java的反射机制相关的API来访问annotation信息。相关类(框架或工具中的类)根据这些信息来决定如何使用该程序元素或改变它们的行为。 annotation是不会影响程序代码的执行,无论annotation怎么变化,代码都始终如一地执行。 Java语言解释器在工作时会忽略这些annotation,因此在JVM 中这些annotation是"不起作用"的,只能通过配套的工具才能对这些 annotation 类型的信息进行访问和处理。 Annotation 与interface的异同 Annotation类型使用关键字@interface而不是interface。 这个关键字声明隐含了一个信息: 它是继承了java.lang.annotation.Annotation接口,并非声明了一个interface。 Annotation类型、方法定义是独特的、受限制的。 Annotation 类型的方法必须声明为无参数、无异常抛出的。这些方法定义了annotation的成员: 方法名成为了成员名,而方法返回值成为了成员的类型。方法返回值类型必须为primitive类型、Class类型、枚举类型、annotation类型或者由前面类型之一作为元素的一维数组。方法的后面可以使用 default 和一个默认数值来声明成员的默认值,null 不能作为成员默认值,这与我们在非 annotation 类型中定义方法有很大不同。 Annotation 类型和它的方法不能使用 annotation 类型的参数、成员不能是 generic。只有返回值类型是Class的方法可以在annotation类型中使用generic,因为此方法能够用类转换将各种类型转换为Class。 Annotation类型又与接口有着近似之处。 它们可以定义常量、静态成员类型(比如枚举类型定义)。Annotation类型也可以如接口一般被实现或者继承。 应用场合 annotation一般作为一种辅助途径,应用在软件框架或工具中,在这些工具类中根据不同的 annotation 注解信息采取不同的处理过程或改变相应程序元素(类、方法及成员变量等)的行为。 例如: Junit、Struts、Spring等流行工具框架中均广泛使用了 annotation 。使代码的灵活性大提高。 常见标准的Annotation 从java5版本开始,自带了三种标准 annotation 类型: Override java.lang.Override 是一个marker annotation类型,它被用作标注方法。它说明了被标注的方法重载了父类的方法,起到了断言的作用。如果我们使用了这种annotation在一个没有覆盖父类方法的方法时,java编译器将以一个编译错误来警示。 这个annotaton常常在我们试图覆盖父类方法而确又写错了方法名时加一个保障性的校验过程。 Deprecated Deprecated也是一种marker annotation。当一个类型或者类型成员使用@Deprecated修饰的话,编译器将不鼓励使用这个被标注的程序元素。所以使用这种修饰具有一定的 “延续性”: 如果我们在代码中通过继承或者覆盖的方式使用了这个过时的类型或者成员,虽然继承或者覆盖后的类型或者成员并不是被声明为 @Deprecated,但编译器仍然要报警。 注意: @Deprecated这个annotation类型和javadoc中的 @deprecated这个tag是有区别的: 前者是java编译器识别的,而后者是被javadoc工具所识别用来生成文档(包含程序成员为什么已经过时、它应当如何被禁止或者替代的描述)。 SuppressWarnings 此注解能告诉Java编译器关闭对类、方法及成员变量的警告。 有时编译时会提出一些警告,对于这些警告有的隐藏着Bug,有的是无法避免的,对于某些不想看到的警告信息,可以通过这个注解来屏蔽。 SuppressWarning不是一个marker annotation。它有一个类型为String[]的成员,这个成员的值为被禁止的警告名。对于javac编译器来讲,被-Xlint选项有效的警告名也同样对@SuppressWarings有效,同时编译器忽略掉无法识别的警告名。 annotation语法允许在annotation名后跟括号,括号中是使用逗号分割的name=value对用于为annotation的成员赋值: 代码: @SuppressWarnings(value={“unchecked”,“fallthrough”}) ...

2011-12-26 · 8 min · 1532 words · -

JNDI

JNDI JNDI (Java Naming and Directory Interface,Java命名和目录接口) 是一组在Java应用中访问命名和目录服务的API。命名服务将名称和对象联系起来,使得我们可以用名称访问对象。目录服务是一种命名服务,在这种服务里,对象不但有名称,还有属性。 英文全称是:Java Naming and Directory InterfaceS 术语解释: 一组帮助做多个命名和目录服务接口的API。 JNDI(Java Naming and Directory Interface)是SUN公司提供的一种标准的Java命名系统接口,JNDI提供统一的客户端API,通过不同的访问提供者接口JNDI SPI的实现,由管理者将JNDI API映射为特定的命名服务和目录系统,使得Java应用程序可以和这些命名服务和目录服务之间进行交互。集群JNDI实现了高可靠性JNDI[8],通过服务器的集群,保证了JNDI的负载平衡和错误恢复。在全局共享的方式下,集群中的一个应用服务器保证本地JNDI树的独立性,并拥有全局的JNDI树。每个应用服务器在把部署的服务对象绑定到自己本地的JNDI树的同时,还绑定到一个共享的全局JNDI树,实现全局JNDI和自身JNDI的联系。 JNDI(Java Naming and Directory Interface)是一个应用程序设计的API,为开发人员提供了查找和访问各种命名和目录服务的通用、统一的接口,类似JDBC都是构建在抽象层上。 JNDI可访问的现有的目录及服务有: DNS、XNam 、Novell目录服务、LDAP(Lightweight Directory Access Protocol 轻型目录访问协议)、 CORBA对象服务、文件系统、Windows XP/2000/NT/Me/9x的注册表、RMI、DSML v1&v2、NIS。 JNDI优点 包含了大量的命名和目录服务,使用通用接口来访问不同种类的服务; 可以同时连接到多个命名或目录服务上; 建立起逻辑关联,允许把名称同Java对象或资源关联起来,而不必知道对象或资源的物理ID。 JNDI程序包: javax.naming: 命名操作; javax.naming.directory: 目录操作; javax.naming.event: 在命名目录服务器中请求事件通知; javax.naming.ldap: 提供LDAP支持; javax.naming.spi: 允许动态插入不同实现。 利用JNDI的命名与服务功能来满足企业级API对命名与服务的访问,诸如EJB、JMS、JDBC 2.0以及IIOP上的RMI通过JNDI来使用CORBA的命名服务。 JNDI架构 JNDI架构提供了一组标准的独立于命名系统的API,这些API构建在与命名系统有关的驱动之上。这一层有助于将应用与实际数据源分离,因此不管应用访问的是LDAP、RMI、DNS、还是其他的目录服务。换句话说,JNDI独立于目录服务的具体实现,只要有目录的服务提供接口 (或驱动) ,就可以使用目录。 关于JNDI要注意的重要一点是,它提供了应用编程接口(application programming interface,API)和服务提供者接口(service provider interface,SPI)。这一点的真正含义是,要让应用与命名服务或目录服务交互,必须有这个服务的JNDI服务提供者,这正是JNDI SPI发挥作用的地方。服务提供者基本上是一组类,这些类为各种具体的命名和目录服务实现了JNDI接口—很象JDBC驱动为各种具体的数据库系统实现了JDBC接口一样。作为一个应用开发者,不必操心JNDI SPI。只需要确认要使用的每一个命名或目录服务都有服务提供者。 JNDI组件 1、Javax.naming: 包含了访问命名服务的类和接口。例如,它定义了Context接口,这是命名服务执行查询的入口。 2、Javax.naming.directory: 对命名包的扩充,提供了访问目录服务的类和接口。例如,它为属性增加了新的类,提供了表示目录上下文的DirContext接口,定义了检查和更新目录对象的属性的方法。 3、Javax.naming.event: 提供了对访问命名和目录服务时的时间通知的支持。例如,定义了NamingEvent类,这个类用来表示命名/目录服务产生的事件,定义了侦听NamingEvents的NamingListener接口。 4、Javax.naming.ldap: 这个包提供了对LDAP 版本3扩充的操作和控制的支持,通用包javax.naming.directory没有包含这些操作和控制。 5、Javax.naming.spi: 这个包提供了一个方法,通过javax.naming和有关包动态增加对访问命名和目录服务的支持。这个包是为有兴趣创建服务提供者的开发者提供的。 JNDI用途 命名或目录服务使用户可以集中存储共有信息,这一点在网络应用中是重要的,因为这使得这样的应用更协调、更容易管理。例如,可以将打印机设置存储在目录服务中,以便被与打印机有关的应用使用。 我们大家每天都不知不觉地使用了命名服务。命名系统中的对象可以是DNS记录中的名称、应用服务器中的EJB组件(Enterprise JavaBeans Component)、LDAP(Lightweight Directory Access Protocol)中的用户Profile。 目录服务是命名服务的自然扩展。两者之间的关键差别是目录服务中对象可以有属性 (例如,用户有email地址) ,而命名服务中对象没有属性。因此,在目录服务中,你可以根据属性搜索对象。JNDI允许你访问文件系统中的文件,定位远程RMI注册的对象,访问象LDAP这样的目录服务,定位网络上的EJB组件。 对于象LDAP 客户端、应用launcher、类浏览器、网络管理实用程序,甚至地址薄这样的应用来说,JNDI是一个很好的选择。 JNDI可访问的现有的目录及服务有: DNS、XNam 、Novell目录服务、LDAP(Lightweight Directory Access Protocol 轻型目录访问协议)、 CORBA对象服务、文件系统、Windows XP/2000/NT/Me/9x的注册表、RMI、DSML v1&v2、NIS JNDI与JDBC JNDI提供了一种统一的方式,可以用在网络上查找和访问服务。通过指定一个资源名称,该名称对应于数据库或命名服务中的一个记录,同时返回数据库连接建立所必须的信息。 JNDI主要有两部分组成: 应用程序编程接口和服务供应商接口。应用程序编程接口提供了Java应用程序访问各种命名和目录服务的功能,服务供应商接口提供了任意一种服务的供应商使用的功能。 代码示例: try{ Context cntxt = new InitialContext(); DataSource ds = (DataSource) cntxt.lookup("jdbc/dpt"); } catch(NamingException ne){ ... } JNDI与JMS 消息通信是软件组件或应用程序用来通信的一种方法。JMS就是一种允许应用程序创建、发送、接收、和读取消息的JAVA技术。 代码示例: try{ Properties env = new Properties(); InitialContext inictxt = new InitialContext(env); TopicConnectionFactory connFactory = (TopicConnectionFactory) inictxt.lookup("TTopicConnectionFactory"); ... } catch(NamingException ne){ ... } 访问特定目录: 举个例子,人是个对象,他有好几个属性,诸如这个人的姓名、电话号码、电子邮件地址、邮政编码等属性。通过getAttributes()方法 Attribute attr = directory.getAttributes(personName).get("email"); String email = (String)attr.get(); 通过使用JNDI让客户使用对象的名称或属性来查找对象: foxes = directory.search("o=Wiz,c=US", "sn=Fox", controls); 通过使用JNDI来查找诸如打印机、数据库这样的对象,查找打印机的例子: Printer printer = (Printer)namespace.lookup(printerName); printer.print(document); 浏览命名空间: NamingEnumeration list = namespace.list("o=Widget, c=US"); while (list.hasMore()) { NameClassPair entry = (NameClassPair)list.next(); display(entry.getName(), entry.getClassName()); } 常用的JNDI操作 void bind(String sName,Object object);――绑定: 把名称同对象关联的过程 void rebind(String sName,Object object);――重新绑定: 用来把对象同一个已经存在的名称重新绑定 void unbind(String sName);――释放: 用来把对象从目录中释放出来 Object lookup(String sName);――查找: 返回目录中的一个对象 void rename(String sOldName,String sNewName);――重命名: 用来修改对象名称绑定的名称 NamingEnumeration listBinding(String sName);――清单: 返回绑定在特定上下文中对象的清单列表 NamingEnumeration list(String sName); 代码示例: 重新得到了名称、类名和绑定对象。 NamingEnumeration namEnumList = ctxt.listBinding("cntxtName"); ... while ( namEnumList.hasMore() ) { Binding bnd = (Binding) namEnumList.next(); String sObjName = bnd.getName(); String sClassName = bnd.getClassName(); SomeObject objLocal = (SomeObject) bnd.getObject(); } JNDI 是什么 http://blog.csdn.net/zhaosg198312/article/details/3979435 ...

2011-12-25 · 3 min · 451 words · -

JTA

JTA JTA,即Java Transaction API,译为Java事务API。 JTA允许应用程序执行分布式事务处理——在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序的JTA支持极大地增强了数据访问能力。 JTA和JTS Java事务API (JTA: Java Transaction API) 和它的同胞Java事务服务 (JTS: Java Transaction Service) ,为J2EE平台提供了分布式事务服务 (distributed transaction) 。 一个分布式事务 (distributed transaction) 包括一个事务管理器 (transaction manager) 和一个或多个资源管理器(resource manager)。 一个资源管理器 (resource manager) 是任意类型的持久化数据存储。 事务管理器 (transaction manager) 承担着所有事务参与单元者的相互通讯的责任。 JTA与JDBC JTA事务比JDBC事务更强大。一个JTA事务可以有多个参与者,而一个JDBC事务则被限定在一个单一的数据库连接。下列任一个Java平台的组件都可以参与到一个JTA事务中: JDBC连接、JDO PersistenceManager 对象、JMS 队列、JMS 主题、企业JavaBeans (EJB) 、一个用J2EE Connector Architecture 规范编译的资源分配器。

2011-12-25 · 1 min · 48 words · -

Comparable

Comparable Comparable 是排序接口。 若一个类实现了Comparable接口,就意味着“该类支持排序”。 即然实现Comparable接口的类支持排序,假设现在存在“实现Comparable接口的类的对象的List列表(或数组)”,则该List列表(或数组)可以通过 Collections.sort (或 Arrays.sort)进行排序。 此外,“实现Comparable接口的类的对象”可以用作“有序映射(如TreeMap)”中的键或“有序集合(TreeSet)”中的元素,而不需要指定比较器。 Comparable 定义 Comparable 接口仅仅只包括一个函数,它的定义如下: package java.lang; import java.util.*; public interface Comparable { public int compareTo(T o); } 说明: 假设我们通过 x.compareTo(y) 来“比较x和y的大小”。若返回“负数”,意味着“x比y小”;返回“零”,意味着“x等于y”;返回“正数”,意味着“x大于y”。 Comparator 简介 Comparator 是比较器接口。 我们若需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口);那么,我们可以建立一个“该类的比较器”来进行排序。这个“比较器”只需要实现Comparator接口即可。 也就是说,我们可以通过“实现Comparator类来新建一个比较器”,然后通过该比较器对类进行排序。 Comparator 定义 Comparator 接口仅仅只包括两个个函数,它的定义如下: 复制代码 package java.util; public interface Comparator { int compare(T o1, T o2); boolean equals(Object obj); } 复制代码 说明: (01) 若一个类要实现Comparator接口:它一定要实现compareTo(T o1, T o2) 函数,但可以不实现 equals(Object obj) 函数。 ...

2011-12-01 · 1 min · 91 words · -

观察者模式, Observer pattern

观察者模式, Observer pattern 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 观察者模式 (Observer)又称发布-订阅模式 (Publish-Subscribe:Pub/Sub)。它是一种通知机制,让发送通知的一方 (被观察方)和接收通知的一方 (观察者)能彼此分离,互不影响。 观察者模式 (有时又被称为发布-订阅模式、模型-视图模式、源-收听者模式或从属者模式) 是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过调用各观察者所提供的方法来实现。此种模式通常被用来实作事件处理系统。 此模式完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是: 系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。 观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色: 观察者和被观察对象。在刚才的例子中,业务数据是被观察对象,用户界面是观察者。观察者和被观察者之间存在"观察"的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应。如果在用户界面、业务数据之间使用这样的观察过程,可以确保界面和数据之间划清界限,假定应用程序的需求发生变化,需要修改界面的表现,只需要重新构建一个用户界面,业务数据不需要发生变化。 实现观察者模式的时候要注意,观察者和被观察对象之间的互动关系不能体现成类之间的直接调用,否则就将使观察者和被观察对象之间紧密的耦合起来,从根本上违反面向对象的设计的原则。无论是观察者"观察"观察对象,还是被观察者将自己的改变"通知"观察者,都不应该直接调用。 实现观察者模式有很多形式,比较直观的一种是使用一种"注册——通知——撤销注册"的形式。 @startuml class Publisher interface Subscriber Publisher o-right- Subscriber class ConcreateSubscriber Subscriber <|-- ConcreateSubscriber class Client ConcreateSubscriber <.. Client Publisher<--Client @enduml @startuml class Demo class Editor note right: 发布者\nPublisher\n被观察对象\nSubject Editor<-- Demo interface EventListener note left: 订阅者\nSubscriber\n观察者\nObserver class EmailNotificationListener note left: 具体订阅者 EventListener<|-- EmailNotificationListener EmailNotificationListener<.. Demo class EventManager EventManager --o Editor EventListener -right-o EventManager class LogOpenListener EventListener<|-- LogOpenListener LogOpenListener<.. Demo @enduml 发布者, Publisher, 被观察对象, Subject 发布者 (Publisher) 会向其他对象发送值得关注的事件。 事件会在发布者自身状态改变或执行特定行为后发生。 发布者中包含一个允许新订阅者加入和当前订阅者离开列表的订阅构架。 ...

2011-11-20 · 3 min · 620 words · -

TimeUnit

TimeUnit http://chenjumin.iteye.com/blog/2182171 //关于秒的常用方法 TimeUnit.SECONDS.toMillis(1) 1秒转换为毫秒数 TimeUnit.SECONDS.toMinutes(60) 60秒转换为分钟数 TimeUnit.SECONDS.sleep(5) 线程休眠5秒 TimeUnit.SECONDS.convert(1, TimeUnit.MINUTES) 1分钟转换为秒数 //TimeUnit.DAYS 日的工具类 //TimeUnit.HOURS 时的工具类 //TimeUnit.MINUTES 分的工具类 //TimeUnit.SECONDS 秒的工具类 //TimeUnit.MILLISECONDS 毫秒的工具类 http://www.importnew.com/7219.html TimeUnit是什么 TimeUnit是java.util.concurrent包下面的一个类,TimeUnit提供了可读性更好的线程暂停操作,通常用来替换 Thread.sleep(),在很长一段时间里 Thread的sleep() 方法作为暂停线程的标准方式,几乎所有Java程序员都熟悉它,事实上sleep方法本身也很常用而且出现在很多面试中。如果你已经使用过 Thread.sleep(),当然我确信你这样做过,那么你一定熟知它是一个静态方法,暂停线程时它不会释放锁,该方法会抛出 InterrupttedException 异常 (如果有线程中断了当前线程) 。但是我们很多人并没有注意的一个潜在的问题就是它的可读性。Thread.sleep() 是一个重载方法,可以接收长整型毫秒和长整型的纳秒参数,这样对程序员造成的一个问题就是很难知道到底当前线程是睡眠了多少秒、分、小时或者天。看看下面这个Thread.sleep()方法: Thread.sleep (2400000) 粗略一看,你能计算出当前线程是等待多长时间吗?可能有些人可以,但是对于大多数程序员来说这种写法的可读性还是很差的,你需要把毫秒转换成秒和分,让我们来看看另外一个例子,这个例子比前面那个例子可读性稍微好一点: Thread.sleep(4_60_1000); 这比前面那个例子已经好多了,但是仍然不是最好的,你注意到睡眠时间用毫秒,不容易猜出当前线程将等待4分钟。TimeUnit类解决了这个问题,通过指定DAYS、HOURS、MINUTES,SECONDS、MILLISECONDS和NANOSECONDS。java.utils.concurrent .TimeUnit 是Java枚举应用场景中最好的例子之一,所有TimeUnit都是枚举实例,让我们来看看线程睡眠4分钟用TimeUnit是如何使用的。 TimeUnit.MINUTES.sleep(4); // sleeping for 4 minutes 类似你可以采用秒、分、小时级别来暂停当前线程。你可以看到这比Thread的sleep方法的可读的好多了。记住TimeUnit.sleep()内部调用的Thread.sleep()也会抛出InterruptException。你也可以查看JDK源代码去验证一下。下面是一个简单例子,它展示如果使用TimeUnit.sleep()方法。 public class TimeUnitTest { public static void main(String args[]) throws InterruptedException { System.out.println("Sleeping for 4 minutes using Thread.sleep()"); Thread.sleep(4 * 60 * 1000); System.out.println("Sleeping for 4 minutes using TimeUnit sleep()"); TimeUnit.SECONDS.sleep(4); TimeUnit.MINUTES.sleep(4); TimeUnit.HOURS.sleep(1); TimeUnit.DAYS.sleep(1); } } 除了sleep的功能外,TimeUnit还提供了便捷方法用于把时间转换成不同单位,例如,如果你想把秒转换成毫秒,你可以使用下面代码: ...

2011-11-19 · 1 min · 93 words · -

commons-logging Log4J

commons-logging Log4J commons-logging vs Log4J Log4J是一个功能很强大的日志记录组件,它提供了丰富的日志记录功能,它本身和commons-logging没有什么关系,也就是说一个项目中可以单独使用Log4J来记录日志,而不需要引入commons-logging包,这样也能实现记录日志的功能,但是这样有一个不太好的地方就是如果你想使用其他的Logging组建,比如jdk1.4自带的logging框架,就不得不修改原有文件中所有使用了Log4J组建的代码。 这时,commons-logging就派上用场了,说白了commons-logging就是一个记录日志的统一接口,它定义了一套抽象的记录日志的接口,用户可以通过配置,来使用任何一个符合该接口的Logging组建。而commons-logging组建本身仅仅提供了一个很简单的记录日志的类SimpleLog,这个类的记录日志功能很有限。因此,通常情况下,会将Log4J组建与commons-logging组建一块儿使用,在程序代码中,使用commons-logging的接口方法来记录日志,而后台实际使用的是Log4J组建。 commons-logging组建使用具体的Log组建的顺序如下 如果定义了org.apache.commons.logging.Log系统参数,则使用指定的Logging实现; 如果在CLASSPATH里发现了Log4J,则使用Log4J; 如果使用的是JDK1.4,则使用JDK1.4内置的Logging框架; 如果都没有找到,则使用Commons Logging内置的简单Log实现。 我们在做项目时,日志的记录是必不可少的一项任务,而我们通常是使用 apache 的 log4j 日志管理工具。然而,在项目中,我们经常会看到两个 jar 包: commons-logging.jar 和 log4j.rar。为什么我们在使用 log4j 的同时还要引入 commons-logging.jar 呢,或者说不用 commons-logging.jar 可不可以,这两者之间到底是怎么的一种关系呢? 作为记录日志的工具,它至少应该包含如下几个组成部分(组件): Logger 记录器组件负责产生日志,并能够对日志信息进行分类筛选,控制什么样的日志应该被输出,什么样的日志应该被忽略。它还有一个重要的属性 - 日志级别。不管何种日志记录工具,大概包含了如下几种日志级别: DEBUG, INFO, WARN, ERROR 和 FATAL。 Level 日志级别组件。 Appender 日志记录工具基本上通过 Appender 组件来输出到目的地的,一个 Appender 实例就表示了一个输出的目的地。 Layout Layout 组件负责格式化输出的日志信息,一个 Appender 只能有一个 Layout。 我们再来看看 log4j.jar,打开 jar 包,我们可以看到 Logger.class(Logger),Level.class(Level), FileAppender.class(Appender), HTMLLayout.class(Layout)。其它的我们先忽略不看,这几个字节码文件正好是记录日志必不可少的几个组件。 接下来看看 commons-logging 中的 org.apache.commons.logging.Log.java 源码: Java代码 package org.apache.commons.logging; public interface Log { ...

2011-11-18 · 2 min · 331 words · -

tomcat config, server, user

tomcat config, server, user server Listener 监听器,用来监听某些事件的发生。 VersionLoggerListener,启动时对tomcat,java,操作系统信息打印日志。 JreMemoryLeakPreventionListener, JreMemoryLeakPreventionListener,防止内存溢出的监听器。 http://liuxi.name/blog/20160608/jvm-full-gc-hourly.html GlobalResourcesLifecycleListener,初始化定义在元素GlobalNamingResources下的全局JNDI资源 ThreadLocalLeakPreventionListener,防止ThreadLocal溢出监听器。 connectionTimeout - 网络连接超时,单位: 毫秒。设置为0表示永不超时,这样设置有隐患的。通常可设置为30000毫秒。 keepAliveTimeout - 长连接最大保持时间 (毫秒) user config Tomcat 6 <?xml version='1.0' encoding='utf-8'?> <tomcat-users> <role rolename="tomcat"/> <role rolename="role1"/> <role rolename="manager"/> <role rolename="admin"/> <user username="tomcat" password="tomcat" roles="tomcat"/> <user username="both" password="tomcat" roles="tomcat,role1"/> <user username="role1" password="tomcat" roles="role1"/> <user username="admin" password="admin" roles="admin,manager"/> <user username="hhh" password="123456" roles="role1,tomcat,admin,manager"/> </tomcat-users> Tomcat 7 <role rolename="manager"/> <role rolename="manager-gui"/> <role rolename="admin"/> <role rolename="admin-gui"/> <user username="tomcat" password="tomcat" roles="admin-gui,admin,manager-gui,manager"/>

2011-11-12 · 1 min · 72 words · -

Jakarta

Jakarta http://zh.wikipedia.org/zh-cn/Jakarta%E9%A1%B9%E7%9B%AE Jakarta项目是在Apache软件基金会营运的开放源代码开发项目之一。开发着面向对象编程语言Java的程序库,框架等。 Jakarta是Apache组织下的一套Java解决方案的开源软件的名称,它包括了很多子项目。Tomcat、Ant、Struts等等现在是Apache下的开源项目,也曾是Jakarta的关联项目。 Jakarta的名称是想把与Jakarta关系非常深的爪哇岛关联起来。编程语言Java的命名源自这个岛的名字 (印尼语: Jawa、英语: Java) ,而城市雅加达 (Jakarta) 正是这个岛上的第一大城市,也是印度尼西亚的首府。 子项目 其中,Jakarta项目所包括的相关工具、库以及框架等罗列如下: BCEL - 处理Java字节码的类库 BSF - 脚本程序框架 Cactus - 服务器端Java类测试工具框架 ECS - The Element Construction Set is a Java API for generating elements for various markup anguages. HttpComponents- 超文本传输协议. JCS - 分布式缓存系统. JMeter - 压力测试工具 ORO - Java类库,提供与Perl5兼容的正则表达式功能 Regexp - 纯Java正则表达式包 Slide - a content repository primarily using WebDAV. Taglibs - 一个代码库,用于支持开发定制化的JSP tag lib 以前隶属于Jakarta项目,但现在作为Apache软件基金的单独项目,有: Ant - 构建工具 Commons - 一组使用类的合集,主要作为Java标准库的补充 HiveMind - a services and configuration microkernel ...

2011-11-12 · 1 min · 111 words · -

Collection, Array, Vector, ArrayList, List, LinkedList

Collection, Array, Vector, ArrayList, List, LinkedList array(数组)和Vector是十分相似的Java构件 (constructs) ,两者全然不同,在选择使用时应根据各自的功能来确定。 数组 Array Java arrays 的元素个数不能下标越界,从很大程度上保证了Java程序的安全性,而其他一些语言出现这一问题时常导致灾难性的后果。 Array 可以存放Object和基本数据类型,但创建时必须指定数组的大小,并不能再改变。值得注意的是: 当Array中的某一元素存放的是Objrct reference 时,Java不会调用默认的构造函数,而是将其初值设为null,当然这跟Java对各类型数据赋默认值的规则是一样的,对基本数据类型同样适用。 线性表,链表,哈希表是常用的数据结构,在进行Java开发时,JDK已经为我们提供了一系列相应的类来实现基本的数据结构。这些类均在java.util包中。本文试图通过简单的描述,向读者阐述各个类的作用以及如何正确使用这些类。 Collection接口 Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素 (Elements) 。一些 Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection的类, Java SDK提供的类都是继承自Collection的"子接口"如List和Set。 所有实现Collection接口的类都必须提供两个标准的构造函数: 无参数的构造函数用于创建一个空的Collection,有一个Collection参数的构造函数用于创建一个新的 Collection,这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection。 如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下: Iterator it = collection.iterator(); // 获得一个迭代子 while(it.hasNext()) { Object obj = it.next(); // 得到下一个元素 } 由Collection接口派生的两个接口是List和Set。 List接口 List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引 (元素在List中的位置,类似于数组下标) 来访问List中的元素,这类似于Java的数组。 和下面要提到的Set不同,List允许有相同的元素。 除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个 ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素,还能向前或向后遍历。 实现List接口的常用类有LinkedList,ArrayList,Vector和Stack。 LinkedList类 LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在 LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈 (stack) ,队列 (queue) 或双向队列 (deque) 。 注意LinkedList没有同步方法。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List: List list = Collections.synchronizedList(new LinkedList(…)); ...

2011-11-09 · 3 min · 469 words · -

html5 video

html5 video HTML5 video 元素支持三种视频格式: Ogg = 带有 Theora 视频编码和 Vorbis 音频编码的 Ogg 文件 MPEG4 = 带有 H.264 视频编码和 AAC 音频编码的 MPEG 4 文件 WebM = 带有 VP8 视频编码和 Vorbis 音频编码的 WebM 文件

2011-10-31 · 1 min · 33 words · -

代码覆盖率浅谈

代码覆盖率浅谈 http://www.cnblogs.com/coderzh/archive/2009/03/29/1424344.html 在做单元测试时,代码覆盖率常常被拿来作为衡量测试好坏的指标,甚至,用代码覆盖率来考核测试任务完成情况,比如,代码覆盖率必须达到80%或 90%。于是乎,测试人员费尽心思设计案例覆盖代码。用代码覆盖率来衡量,有利也有有弊。本文我们就代码覆盖率展开讨论,也欢迎同学们踊跃评论。 首先,让我们先来了解一下所谓的"代码覆盖率"。我找来了所谓的定义: 代码覆盖率 = 代码的覆盖程度,一种度量方式。 上面简短精悍的文字非常准确的描述了代码覆盖率的含义。而代码覆盖程度的度量方式是有很多种的,这里介绍一下最常用的几种: 1. 语句覆盖(StatementCoverage) 又称行覆盖(LineCoverage),段覆盖(SegmentCoverage),基本块覆盖(BasicBlockCoverage),这是最常用也是最常见的一种覆盖方式,就是度量被测代码中每个可执行语句是否被执行到了。这里说的是"可执行语句",因此就不会包括像C++的头文件声明,代码注释,空行,等等。非常好理解,只统计能够执行的代码被执行了多少行。需要注意的是,单独一行的花括号{} 也常常被统计进去。语句覆盖常常被人指责为"最弱的覆盖",它只管覆盖代码中的执行语句,却不考虑各种分支的组合等等。假如你的上司只要求你达到语句覆盖,那么你可以省下很多功夫,但是,换来的确实测试效果的不明显,很难更多地发现代码中的问题。 这里举一个不能再简单的例子,我们看下面的被测试代码: int foo(int a, int b) { return a / b; } 假如我们的测试人员编写如下测试案例: TeseCase: a = 10, b = 5 测试人员的测试结果会告诉你,他的代码覆盖率达到了100%,并且所有测试案例都通过了。然而遗憾的是,我们的语句覆盖率达到了所谓的100%,但是却没有发现最简单的Bug,比如,当我让b=0时,会抛出一个除零异常。 正因如此,假如上面只要求测试人员语句覆盖率达到多少的话,测试人员只要钻钻空子,专门针对如何覆盖代码行编写测试案例,就很容易达到主管的要求。当然了,这同时说明了几个问题: 1.主管只使用语句覆盖率来考核测试人员本身就有问题。 2.测试人员的目的是为了测好代码,钻如此的空子是缺乏职业道德的。 3.是否应该采用更好的考核方式来考核测试人员的工作? 为了寻求更好的考核标准,我们必须先了解完代码覆盖率到底还有哪些,如果你的主管只知道语句覆盖,行覆盖,那么你应该主动向他介绍还有更多的覆盖方式。比如: 2. 判定覆盖(DecisionCoverage) 又称分支覆盖(BranchCoverage),所有边界覆盖(All-EdgesCoverage),基本路径覆盖(BasicPathCoverage),判定路径覆盖(Decision-Decision-Path)。它度量程序中每一个判定的分支是否都被测试到了。这句话是需要进一步理解的,应该非常容易和下面说到的条件覆盖混淆。因此我们直接介绍第三种覆盖方式,然后和判定覆盖一起来对比,就明白两者是怎么回事了。 3. 条件覆盖(ConditionCoverage) 它度量判定中的每个子表达式结果true和false是否被测试到了。为了说明判定覆盖和条件覆盖的区别,我们来举一个例子,假如我们的被测代码如下: int foo(int a, int b) { if (a < 10 || b < 10) // 判定 { return 0; // 分支一 } else { return 1; // 分支二 } } ...

2011-10-31 · 2 min · 305 words · -

CXF Axis2

CXF Axis2 http://apache-cxf.group.iteye.com/group/wiki/1252 新一代的 Web Services 框架如 Axis2、CXF 都是由现有的项目中逐渐演化而来的,Axis2 是由大家熟悉的 Axis 1.x 系列演化过来,而 Apache CXF 则是由 Celtix 和 XFire 项目整合而生,并且刚刚发布了 2.0.2 的最新版本,不过仍是 Apache 的一个孵化项目。 Axis2 是对 Axis 进行了彻底的重写的一个新项目了,它使用了新的模块化架构,更方便于功能性的扩展等等。 Apache CXF 则是由 XFire 和 Celtix 两个现有的项目进行了重组。 问题: 如果现有的应用程序是基于 Axis 1.x、XFire 或者 Celtix 的话,那应该怎么办?都迁移到这些新的框架上去吗?但是即使是要迁移,那应该迁移到哪个框架上去呢? 如果是编写一个新的 Web Services 应用程序的话,就不存在迁移的问题了,但是哪个框架是你应当选择进行使用的呢?哪个比哪个更好呢? 对于现在的应用程序的迁移,如果你的应用程序是稳定而成熟的,并且在可预知的未来的情况下,只要很少的一些需求变更要做的话,那么保存你的体力,不要去做"劳民伤财"的迁移工作了。 如果你的现有应用程序BUG缠身,性能,功能等等都一片糟糕的话,那就要考虑迁移了,那选哪个框架呢?先比较一下它们的不同之处: Apache CXF 支持 WS-Addressing、WS-Policy、WS-RM、WS-Security和WS-I BasicProfile Axis2 支持 WS-Addressing、WS-RM、WS-Security和WS-I BasicProfile,WS-Policy将在新版本里得到支持 Apache CXF 是根据Spring哲学来进行编写的,即可以无缝地与Spring进行整合 Axis2 不是 Axis2 支持更多的 data bindings,包括 XMLBeans、JiBX、JaxMe 和 JaxBRI,以及它原生的 data binding (ADB) 。 ...

2011-10-31 · 1 min · 120 words · -

JAX-WS

JAX-WS JAX-WS规范是一组XML web services的JAVA API。JAX-WS允许开发者可以选择RPC-oriented或者message-oriented 来实现自己的web services。 在 JAX-WS中,一个远程调用可以转换为一个基于XML的协议例如SOAP。在使用JAX-WS过程中,开发者不需要编写任何生成和处理SOAP消息的代码。JAX-WS的运行时实现会将这些API的调用转换成为对应的SOAP消息。 在服务器端,用户只需要通过Java语言定义远程调用所需要实现的接口SEI (service endpoint interface) ,并提供相关的实现,通过调用JAX-WS的服务发布接口就可以将其发布为WebService接口。 在客户端,用户可以通过JAX-WS的API创建一个代理 (用本地对象来替代远程的服务) 来实现对于远程服务器端的调用。 当然 JAX-WS 也提供了一组针对底层消息进行操作的API调用,你可以通过Dispatch 直接使用SOAP消息或XML消息发送请求或者使用Provider处理SOAP或XML消息。 通过web service所提供的互操作环境,我们可以用JAX-WS轻松实现JAVA平台与其他编程环境 (.net等) 的互操作。 JAX-WS与JAX-RPC之间的关系 Sun最开始的web services的实现是JAX-RPC 1.1 (JSR 101)。这个实现是基于Java的RPC,并不完全支持schema规范,同时没有对Binding和Parsing定义标准的实现。 JAX-WS2.0 (JSR 224)是Sun新的web services协议栈,是一个完全基于标准的实现。在binding层,使用的是the Java Architecture for XML Binding (JAXB, JSR 222),在parsing层,使用的是the Streaming API for XML (StAX, JSR 173),同时它还完全支持schema规范。

2011-10-31 · 1 min · 50 words · -

servlet init()

servlet init() init方法是在Servlet实例化之后执行的,并且只执行一次。 一.先说init(ServletConfig)中参数ServletConfig,代表的是配置信息。即在web.xml中配置的信息,比如: <servlet> <servlet-name>myfirstservlet</servlet-name> <servlet-class>as</servlet-class> <init-param> <param-name>name</param-name> <param-value>小明</param-value> </init-param> <init-param> <param-name>age</param-name> <param-value>25</param-value> </init-param> </servlet> 在程序中可以用this.getServletConfig()方法得到ServletConfig的实例,然后用ServletConfig的相应方法 可以得到ServletConfig的名字(getServletName)和配置参数的名字(getInitParameter(“name”))或者 名字枚举(getInitParameterNames()),并且通过参数名字得到相应的参数值。具体方法参见API。 二.再说说init方法,从源码中我们不难发现: Servlet接口里面只有init(ServletConfig),这是供tomcat调用的。GenericServlet类里面有成员变量ServletConfig,init(ServletConfig)方法和init()方法: private transient ServletConfig config; public void init(ServletConfig config) throws ServletException{ this.config=config; this.init(); } public void init() throws ServletException{ } 现在一切都很明了了,当容器(tomcat)帮忙调用init(ServletConfig config)并且给传过来一个参数config,这个方法把参数对象的引用指向类的成员变量this.config,并且调用类的 this.init()方法。有人问了,我们在写Servlet类时只要重写init(ServletConfig config)就可以了,init()不就成了多余的了吗?实际上init()方法是为了防止程序员在写Servlet类重写 init(ServletConfig config)时忘记写super.init(ServletConfig config),这样就容易造成出现空指针异常。而这就要求我们最好不要重写init(ServletConfig config),而要重写init()方法,就可以不写super。Servlet,你真是绕死人不偿命!

2011-10-30 · 1 min · 48 words · -

Servlet生命周期

Servlet生命周期 Servlet运行在Servlet容器中,其生命周期由容器来管理。Servlet的生命周期通过javax.servlet.Servlet接口中的init()、service()和destroy()方法来表示。 Servlet的生命周期包含了下面4个阶段: (1) 加载和实例化 Servlet容器负责加载和实例化Servlet。当Servlet容器启动时,或者在容器检测到需要这个Servlet来响应第一个请求时,创建Servlet实例。当Servlet容器启动后,它必须要知道所需的Servlet类在什么位置,Servlet容器可以从本地文件系统、远程文件系统或者其他的网络服务中通过类加载器加载Servlet类,成功加载后,容器创建Servlet的实例。因为容器是通过Java的反射API来创建Servlet实例,调用的是Servlet的默认构造方法 (即不带参数的构造方法) ,所以我们在编写Servlet类的时候,不应该提供带参数的构造方法。 (2) 初始化 在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象。初始化的目的是为了让Servlet对象在处理客户端请求前完成一些初始化的工作,如建立数据库的连接,获取配置信息等。对于每一个Servlet实例,init()方法只被调用一次。在初始化期间,Servlet实例可以使用容器为它准备的ServletConfig对象从Web应用程序的配置信息 (在web.xml中配置) 中获取初始化的参数信息。在初始化期间,如果发生错误,Servlet实例可以抛出ServletException异常或者UnavailableException异常来通知容器。ServletException异常用于指明一般的初始化失败,例如没有找到初始化参数;而UnavailableException异常用于通知容器该Servlet实例不可用。例如,数据库服务器没有启动,数据库连接无法建立,Servlet就可以抛出UnavailableException异常向容器指出它暂时或永久不可用。 (3) 请求处理 Servlet容器调用Servlet的service()方法对请求进行处理。要注意的是,在service()方法调用之前,init()方法必须成功执行。在service()方法中,Servlet实例通过ServletRequest对象得到客户端的相关信息和请求信息,在对请求进行处理后,调用ServletResponse对象的方法设置响应信息。在service()方法执行期间,如果发生错误,Servlet实例可以抛出ServletException异常或者UnavailableException异常。如果UnavailableException异常指示了该实例永久不可用,Servlet容器将调用实例的destroy()方法,释放该实例。此后对该实例的任何请求,都将收到容器发送的HTTP 404 (请求的资源不可用) 响应。如果UnavailableException异常指示了该实例暂时不可用,那么在暂时不可用的时间段内,对该实例的任何请求,都将收到容器发送的HTTP 503 (服务器暂时忙,不能处理请求) 响应。 (4) 服务终止 当容器检测到一个Servlet实例应该从服务中被移除的时候,容器就会调用实例的destroy()方法,以便让该实例可以释放它所使用的资源,保存数据到持久存储设备中。当需要释放内存或者容器关闭时,容器就会调用Servlet实例的destroy()方法。在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收。如果再次需要这个Servlet处理请求,Servlet容器会创建一个新的Servlet实例。 在整个Servlet的生命周期过程中,创建Servlet实例、调用实例的init()和destroy()方法都只进行一次,当初始化完成后,Servlet容器会将该实例保存在内存中,通过调用它的service()方法,为接收到的请求服务。下面给出Servlet整个生命周期过程的UML序列图, 如果需要让Servlet容器在启动时即加载Servlet,可以在web.xml文件中配置元素。 https://skydrive.live.com/embed?cid=37BA55E5B510EC35&resid=37BA55E5B510EC35%21107&authkey=AFYH6_pw58KDkUM

2011-10-30 · 1 min · 28 words · -

PetStore

PetStore PetStore 是 SUN 公司推出的一个宠物商店的系统,其唯一的目的不是让你卖宠物,而是学习 J2EE 最新版本的特性的一个绝好例子。也有不少语言推出相应版本的宠物商店。 Petstore的J2EE设计模式和组件框架思想是最值得学习的两种技术,在PetStore中,真正有关宠物这个具体应用相关的代码很少,整个宠物店是构架在一系列可重用的EJB组件上,这种架构思想值得借鉴。 Petstore只是一种设计思想的展示品,离成熟品有一定距离,性能设计未考虑,.NET曾经将自己精心设计的产品与之相比,这种比较是不公平的,它如同嘲笑模特儿服装不能穿到大街上一样可笑。不过现在,更多轻量JPestore值得学习。

2011-10-29 · 1 min · 9 words · -