??xml version="1.0" encoding="utf-8" standalone="yes"?>日本啊v在线,亚洲精品男人,欧美日韩电影一区二区 http://www.aygfsteel.com/wiflish/category/11012.htmlLoving Life! Loving Coding! zh-cn Tue, 01 Apr 2008 10:34:46 GMT Tue, 01 Apr 2008 10:34:46 GMT 60 JPA annotation http://www.aygfsteel.com/wiflish/archive/2008/04/01/190053.html想飞的鱼 想飞的鱼 Tue, 01 Apr 2008 05:12:00 GMT http://www.aygfsteel.com/wiflish/archive/2008/04/01/190053.html http://www.aygfsteel.com/wiflish/comments/190053.html http://www.aygfsteel.com/wiflish/archive/2008/04/01/190053.html#Feedback 0 http://www.aygfsteel.com/wiflish/comments/commentRss/190053.html http://www.aygfsteel.com/wiflish/services/trackbacks/190053.html 只要@Id的annotation在getterҎ上,将使用getterҎ上的annotationQ忽略属性别的annotation?br /> ]]> [转]Java中的内部cd匿名c?/title> http://www.aygfsteel.com/wiflish/archive/2007/07/01/127344.html想飞的鱼 想飞的鱼 Sun, 01 Jul 2007 03:40:00 GMT http://www.aygfsteel.com/wiflish/archive/2007/07/01/127344.html http://www.aygfsteel.com/wiflish/comments/127344.html http://www.aygfsteel.com/wiflish/archive/2007/07/01/127344.html#Feedback 1 http://www.aygfsteel.com/wiflish/comments/commentRss/127344.html http://www.aygfsteel.com/wiflish/services/trackbacks/127344.html 提vJava内部c(
Inner Class Q可能很多h不太熟悉Q实际上cM的概念在C++里也有,那就是嵌套类Q?strong>Nested ClassQ,
关于q两者的区别与联p,在下文中会有Ҏ。内部类从表面上看,是在类中又定义了一个类Q下文会看到Q内部类可以在很多地方定义)Q而实际上q没有那?
单,乍看上去内部cM乎有些多余,它的用处对于初学者来说可能ƈ不是那么显著Q但是随着对它的深入了解,你会发现Java的设计者在内部cn上的是?
心良苦。学会用内部类Q是掌握Java高~程的一部分Q它可以让你更优雅地设计你的E序l构。下面从以下几个斚w来介l:
public interface Contents {
int value();
}
public interface Destination {
String readLabel();
}
public class Goods {
private class Content implements Contents {
private int i = 11;
public int value() {
return i;
}
}
protected class GDestination implements Destination {
private String label;
private GDestination(String whereTo) {
label = whereTo;
}
public String readLabel() {
return label;
}
}
public Destination dest(String s) {
return new GDestination(s);
}
public Contents cont() {
return new Content();
}
}
class TestGoods {
public static void main (String[] args) {
Goods p = new Goods();
Contents c = p.cont();
Destination d = p.dest("Beijing");
}
}
?
q个例子里类Content和GDestination被定义在了类Goods内部Qƈ且分别有着protected和private修饰W来控制讉KU?
别。Content代表着Goods的内容,而GDestination代表着Goods的目的地。它们分别实C两个接口Content?
Destination。在后面的mainҎ里,直接?
Contents c和Destination dq行操作Q你甚至q这两个内部cȝ名字都没有看见!q样Q内部类的第一个好处就体现出来了—?strong>
隐藏你不惌别h知道的操?/font>Q也卛_装性?
同时Q我们也发现了在外部cM用范围之外得到内部类对象的第一个方法,那就是利用其外部cȝҎ创徏q返回。上例中的cont()和dest()Ҏ是q么做的。那么还有没有别的方法呢Q当然有Q其语法格式如下Q?/p>
outerObject=new outerClass(Constructor Parameters);
outerClass.innerClass innerObject=outerObject.new InnerClass(Constructor Parameters);
注意在创建非静态内部类对象Ӟ一定要先创v相应的外部类对象。至于原因,也就引出了我们下一个话题—?/p>
非静态内部类对象有着指向其外部类对象的引?/strong> 对刚才的例子E作修改Q?/p>
public class Goods {
private valueRate=2;
private class Content implements Contents {
private int i = 11*valueRate;
public int value() {
return i;
}
}
protected class GDestination implements Destination {
private String label;
private GDestination(String whereTo) {
label = whereTo;
}
public String readLabel() {
return label;
}
}
public Destination dest(String s) {
return new GDestination(s);
}
public Contents cont() {
return new Content();
}
}
修改的部分用蓝色昄恕T谡饫镂颐歉鳪oodscd加了一个private成员变量valueRateQ意义是货物?
价值系敎ͼ在内部类Content的方法value()计算价值时把它乘上。我们发玎ͼvalue()可以讉KvalueRateQ这也是内部cȝW二?
好处—?strong>一个内部类对象可以讉K创徏它的外部cd象的内容 Q?
甚至包括U有变量Q这是一个非常有用的Ҏ,为我们在设计时提供了更多的思\和捷径。要惛_现这个功能,内部cd象就必须有指向外部类对象的引用?
Java~译器在创徏内部cd象时Q隐式的把其外部cd象的引用也传了进dƈ一直保存着。这样就使得内部cd象始l可以访问其外部cd象,同时q也是ؓ什
么在外部cM用范围之外向要创建内部类对象必须先创建其外部cd象的原因? 有h会问Q如果内部类里的一个成员变量与外部cȝ一个成员变量同名,也即外部cȝ同名成员变量被屏蔽了Q怎么办?没事QJava里用如下格式表达外部cȝ引用Q?/p>
有了它,我们׃怕这U屏蔽的情况了?/p>
和普通的cMP内部cM可以有静态的。不q和非静态内部类相比Q区别就在于静态内部类没有了指向外部的引用。这实际上和C++中的嵌套cd相像
了,Java内部cMC++嵌套cL大的不同在于是否有指向外部的引用这一点上Q当然从设计的角度以及以它一些细节来讲还有区别?/p>
除此之外Q在M非静态内部类中,都不能有静态数据,静态方法或者又一个静态内部类Q内部类的嵌套可以不止一层)。不q静态内部类中却可以拥有q一切。这也算是两者的W二个区别吧?/p>
是的QJava内部cM可以是局部的Q它可以定义在一个方法甚至一个代码块之内?/p>
public class Goods1 {
public Destination dest(String s) {
class GDestination implements Destination {
private String label;
private GDestination(String whereTo) {
label = whereTo;
}
public String readLabel() { return label; }
}
return new GDestination(s);
}
public static void main (String[] args) {
Goods1 g= new Goods1();
Destination d = g.dest("Beijing");
}
}
上面是q样一个例子。在Ҏdest中我们定义了一个内部类Q最后由q个Ҏq回q个内部cȝ对象。如果我们在用一个内部类的时候仅需要创建它的一个对象ƈ创给外部Q就可以q样做。当Ӟ定义在方法中的内部类可以使设计多样化Q用途绝不仅仅在q一炏V?/p>
下面有一个更怪的例子Q?/p>
public class Goods2{
private void internalTracking(boolean b) {
if(b) {
class TrackingSlip {
private String id;
TrackingSlip(String s) {
id = s;
}
String getSlip() { return id; }
}
TrackingSlip ts = new TrackingSlip("slip");
String s = ts.getSlip();
}
}
public void track() { internalTracking(true ); }
public static void main (String[] args) {
Goods2 g= new Goods2();
g.track();
}
}
你不能在if之外创徏q个内部cȝ对象Q因已经出了它的作用域。不q在~译的时候,内部cTrackingSlip和其他类一样同时被~译Q只不过它由它自q作用域,出了这个范围就无效Q除此之外它和其他内部类q没有区别?/p>
java的匿名内部类的语法规则看上去有些古怪,不过如同匿名数组一P当你只需要创Z个类的对象而且用不上它的名字时Q用内部类可以使代码看上去z清楚。它的语法规则是q样的:
new interfacename(){......}; ?new superclassname(){......};
下面接着前面l箋举例子:
public class Goods3 {
public Contents cont(){
return new Contents (){
private int i = 11;
public int value() {
return i;
}
};
}
}
q里Ҏcont()使用匿名内部cȝ接返回了一个实C接口Contents 的类的对象,看上ȝ十分简z?/p>
在java的事件处理的匿名适配器中Q匿名内部类被大量的使用。例如在惛_闭窗口时加上q样一句代码:
frame.addWindowListener (new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
有一炚w要注意的是,匿名内部cȝ于没有名字,所以它没有构造函敎ͼ但是如果q个匿名内部cȝ承了一个只含有带参数构造函数的父类Q创建它的时候必d?
q些参数Qƈ在实现的q程中用super关键字调用相应的内容Q。如果你惌初始化它的成员变量,有下面几U方法:
如果是在一个方法的匿名内部c,可以利用q个Ҏ传进你想要的参数Q不q记住,q些参数必须被声明ؓfinal? 匿名内部类攚w成有名字的局部内部类Q这样它可以拥有构造函C? 在这个匿名内部类中用初始化代码块? java内部cL什么好处?Z么需要内部类Q?/p>
首先举一个简单的例子Q如果你惛_C个接口,但是q个接口中的一个方法和你构想的q个cM的一个方法的名称Q参数相同,你应该怎么办?q时候,?
可以Z个内部类实现q个接口。由于内部类对外部类的所有内定w是可讉K的,所以这样做可以完成所有你直接实现q个接口的功能?/p>
不过你可能要质疑Q更改一下方法的不就行了吗?
的确Q以此作计内部类的理由,实在没有说服力?/p>
真正的原因是q样的,java中的内部cd接口加在一P可以的解军_被C++E序员抱怨java中存在的一个问题——没有多l承。实际上QC++的多l承设计h很复杂,而java通过内部cd上接口,可以很好的实现多l承的效果?/p>
本文的目的只是向大家介绍一下内部类的概念以及用方法,在后l文章里Q将会针Ҏ文中的内容D更多具体的例子,以及介绍如何使用内部cLZ个Applicaton Framework?/p>
]]> ZStruts的防止页面重复提交的代码片段 http://www.aygfsteel.com/wiflish/archive/2007/04/12/110293.html想飞的鱼 想飞的鱼 Thu, 12 Apr 2007 15:00:00 GMT http://www.aygfsteel.com/wiflish/archive/2007/04/12/110293.html http://www.aygfsteel.com/wiflish/comments/110293.html http://www.aygfsteel.com/wiflish/archive/2007/04/12/110293.html#Feedback 9 http://www.aygfsteel.com/wiflish/comments/commentRss/110293.html http://www.aygfsteel.com/wiflish/services/trackbacks/110293.html //防止重复提交. saveToken(request);
2、在q行数据保存操作的action的方法中Q如saveҎQ,增加如下代码Q?br /> if ( ! isTokenValid(request)) { ActionMessages messages = new ActionMessages(); messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage( " error.submit.double " )); saveMessages(request.getSession(), messages); // 如果是重复提交,重新生成token saveToken(request); return mapping.findForward( " edit " ); } // 不是重复提交׃存数据,q删除该ơ提交的token resetToken(request);
3、在~辑记录的jsp面Q?lt;html:errors />标签Q显C错误提C?br /> ]]> [转]使用JMock来实现孤立测?/title> http://www.aygfsteel.com/wiflish/archive/2007/04/10/109632.html想飞的鱼 想飞的鱼 Tue, 10 Apr 2007 06:40:00 GMT http://www.aygfsteel.com/wiflish/archive/2007/04/10/109632.html http://www.aygfsteel.com/wiflish/comments/109632.html http://www.aygfsteel.com/wiflish/archive/2007/04/10/109632.html#Feedback 0 http://www.aygfsteel.com/wiflish/comments/commentRss/109632.html http://www.aygfsteel.com/wiflish/services/trackbacks/109632.html 使用JMock来实现孤立测??
我们在测试某cLQ由于它要与其他cd生联p,因此往往在测试此cȝ代码中也与之联pȝcM一h试了。这U测试,被测试的cȝ接依赖于其他
c,一旦其他类发生改变Q被试cM随之被迫改变。更重要的是Q这些其他类可能未l过试Q因此必d试q些c,才能试被测试类。这U情况下Q测?
驱动开发成为空谈。而如果其他类中也引用了被试c,我们到底先测试哪一个类Q因此,在测试中Q如果我们能被试cd立v来,使其完全不依赖于其他cȝ
具体实现Q这P我们p做到试先行Q先试哪个c,先实现哪个c,而不与之联pȝcL否已l实现?/p>
虚拟对象(mock
object)是为此需要而诞生的。它通过JDK中的反射机制Q在q行时动态地创徏虚拟对象。在试代码中,我们可以验证q些虚拟对象是否被正地调用
了,也可以在明确的情况下Q让其返回特定的假想倹{而一旦有了这些虚拟对象提供的服务Q被试cd可以虚拟对象作为其他与之联pȝ真实对象的替w,从?
L地搭v一个很完美的测试环境?/p>
JMock是帮助创建mock对象的工P它基于Java开发,在Java试与开发环境中有不可比拟的优势Q更重要的是Q它大大化了虚拟对象的用?/p>
本文中,通过一个简单的试用例来说明JMock如何帮助我们实现q种孤立试。有三个主要的类QUserQUserDAOQ及
UserService。本文中Q我们只需试UserServiceQ准备虚拟UserDAO。对于UserQ由于本w仅是一个过于简单的POJOQ可
以不用测试。但如果你是一个完主义者,也可以用JMock的虚拟它。在q领域,JMock几乎无所不能?)
User是一个POJOQ用以在视图中传输数据及映射数据库。其代码如下Q?/p>
package com.sarkuya.model;
public class User {
private String name;
public User() {
}
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
UserDAO负责与数据库打交道,通过数据库保存、获取User的信息。尽我们可以不用知道JMock如何通过JDK的反机制来实现孤立试Q但?
应知道QJDK的反机制要求这些在q行时创建的动态类必须定义接口。在使用JMock的环境中Q由于我们要虚拟UserDAOQ意味着UserDAO
必须定义接口。代码如下:
package com.sarkuya.dao;
import com.sarkuya.model.User;
public interface UserDAO {
public void saveUser(User user);
public User getUser(Long id);
}
UserService存有UserDAO的引用,通过其对外提供应用的服务。相应地Q我们先定义了其接口(管在本文中Q作试c,UserService不需要有接口Q但如果以后此类需要被虚拟Q也应该带有接口Q基于此原因Q我们也为其定义了接??/p>
package com.sarkuya.service;
import com.sarkuya.dao.UserDAO;
import com.sarkuya.model.User;
public interface UserService {
public void setUserDAO(UserDAO userDAO);
public void saveUser(User user);
public User getUser(Long id);
}
可以看到Q除了setUserDAO()外,其另外的Ҏ与UserDAO一栗这是设计模式中门面模式的典型应用,应用只通过UserService提供服务Q而UserService在内部通过调用UserDAO来实现相应的功能?/p>
Ҏ试先行的原则,你应该先写测试,再编写实现。这里先~写实现的原因,主要是读者更加清楚我们接着要测试什么。由于本文是着重介lJMock的用,加上UserServiceImpl比较单,因此先列出其代码如下Q?/p>
package com.sarkuya.service.impl;
import com.sarkuya.dao.UserDAO;
import com.sarkuya.model.User;
import com.sarkuya.service.UserService;
public class UserServiceImpl implements UserService {
private UserDAO userDAO;
public UserServiceImpl() {
}
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
public User getUser(Long id) {
return userDAO.getUser(id);
}
public void saveUser(User user) {
userDAO.saveUser(user);
}
}
下面是UserService的测试代码:
package com.sarkuya.service;
import com.sarkuya.dao.UserDAO;
import com.sarkuya.model.User;
import com.sarkuya.service.impl.UserServiceImpl;
import junit.framework.*;
import org.jmock.Mock;
import org.jmock.MockObjectTestCase;
public class UserServiceTest extends MockObjectTestCase {
private UserService userService = new UserServiceImpl();
private Mock userDAO = null;
public UserServiceTest(String testName) {
super(testName);
}
protected void setUp() throws Exception {
userDAO = new Mock(UserDAO.class);
userService.setUserDAO((UserDAO)userDAO.proxy());
}
protected void tearDown() throws Exception {
}
public static Test suite() {
TestSuite suite = new TestSuite(UserServiceTest.class);
return suite;
}
public void testGetUser() {
User fakeUser = new User("John");
userDAO.expects(once()).method("getUser").with(eq(1L)).will(returnValue(fakeUser));
User user = userService.getUser(1L);
assertNotNull(user);
assertEquals("John", user.getName());
}
public void testSaveUser() {
User fakeUser = new User("John");
userDAO.expects(once()).method("getUser").with(eq(1L)).will(returnValue(fakeUser));
User user = userService.getUser(1L);
assertEquals("John", user.getName());
userDAO.expects(once()).method("saveUser").with(same(fakeUser));
user.setName("Mike");
userService.saveUser(user);
userDAO.expects(once()).method("getUser").with(eq(1L)).will(returnValue(user));
User modifiedUser = userService.getUser(1L);
assertEquals("Mike", user.getName());
}
}
此段代码有几点应注意Q?/p>
1、此试cȝ承了JMock的MockObjectTestCase
2、private Mock userDAO = null;说明userDao是一个准备虚拟的对象
3、在setup()中,userDAO.class传入Mock()后,再通过proxy()Ҏq回一个UserDAO的代理类实例(卌拟对象实?Qƈ赋guserService
4、在testGetUser()Ҏ中,如果我们先将W一行及W二行代码屏蔽掉Q可以看出,q是一个真实环境下的测试代码。先获取一个UserQ?
然后认光I|再确认其姓名为“John”。此Ӟ在真实环境下Q这D代码要试成功的前提必LUserDAO已经q接C数据库,然后q回一?
User后传lUserService?br />
但问题是Q到目前为止Q且不说UserDAOq未l历q接数据库这一pdJ琐而痛苦的q程Q我们甚臌未实现UserDAO的接口!那么Qؓ何加上第一?
及第二行代码后就可以了呢Q这正是JMock的威力所在。先实例化一个测试用的fakeUserQ然后通过一pd的指令,在第二行代码中告诉JMock?
该如何“做假”。尽这句代码很长,我们可作如下理解Q?br />
1) userDAO.expects(once())Q我们期望userDAO的某Ҏ被执行一ơ,如果此方法未被执行,或者执行了二次以上Q测试就不会通过
2) method("getUser")Q这个期望被执行一ơ的Ҏ名ؓuserDAO.getUser()
3) with(eq(1L))Q执行getUser()ҎӞ认其传入的参数gؓ?L?br />
4) will(returnValue(fakeUser))Q上q条件均满后,q回一个虚假的对象Q即我们前面实例化的fakeUser
M来说Q当讑֮好第二行语句后,JMock在后台监控着Q确保userDAO.getUser()必须Q且只被执行一ơ,且参数?L”已l正地传给了此ҎQ一旦这些条件被满Q就q回fakeUser?br />
而在W三行,User user = userService.getUser(1L)触发所有这些条Ӟ作ؓ奖励Q它接受了奖品fakeUserq赋guser对象。而下面第四行及第五行均对此user对象q行试Q不通过才怪?/p>
5) testSaveUser()Ҏ中的原理cM。其思\是,id为?”的user从数据库中取出,其名改为“Mike”,再存回数据库Q然后再从数据库中取出此userQ确保其名字已被改变?br />
W五行userDAO.expects(once()).method("saveUser").with(same(fakeUser))比较Ҏ。首
先,with(same(fakeUser))说明Q传入参数必LfakeUser此实例,管我们在下面的语句中通过user.setName
("Mike")Q但只是改变了其name的属性,而fakeUser的实例引用ƈ未发生改变,因此可以满条g。其ơ,其后没有.will
(returnValue(fakeUser))Q因为userDAO.saveUser()不需要返回Q何对象或基本数据cd?br />
另外Q当再次执行userDAO.expects()ӞJMock重讑օ监控条g。我们也可以通过userDAO.reset()来显式是清除监控条g?/p>
通过以上实例代码及其说明Q我们看出,用好JMock的关键是先设|监控条Ӟ再写相应的测试语句。一旦设好监控条件后Q在某段代码块执行完毕时Q?
如果监控条g未得到满I或是没有通过expects()再次重设条gQ或通过reset()来显式是清除监控条gQ测试将无法通过?/p>
以上介绍了JMock的基本用方法。而这U基本用法,占了全面掌握JMock所需学习的知?0%以上。关于JMock的更多细节,感兴的读者可以访问JMock的网站进一步学习?/p>
]]>【原创】JIRA安装(windows) http://www.aygfsteel.com/wiflish/archive/2007/04/01/107831.html想飞的鱼 想飞的鱼 Sun, 01 Apr 2007 13:49:00 GMT http://www.aygfsteel.com/wiflish/archive/2007/04/01/107831.html http://www.aygfsteel.com/wiflish/comments/107831.html http://www.aygfsteel.com/wiflish/archive/2007/04/01/107831.html#Feedback 0 http://www.aygfsteel.com/wiflish/comments/commentRss/107831.html http://www.aygfsteel.com/wiflish/services/trackbacks/107831.html 1、环境:Windows XPQtomcat5.0.28Qmysql5.0.37Qapache2.0.59Q?br />2、下载jiraQhttp://downloads.atlassian.com/software/jira/downloads/atlassian-jira-enterprise-3.8-standalone.tar.gz 3、解压到一个目录,jira的根目录?JIRA_HOME%表示Qatlassian-jira-enterprise-3.8-standalone自带了tomcatQ如果已l设|过了CATALINA_HOMEQ更?JIRA_HOME%\bin\startup.bat文gQ找刎ͼ:okHomeQ在其下增加Q?br />cd .. set CATALINA_HOME=%cd% q样更改后,q行%JIRA_HOME%\bin\startup.batp启动jira自带的tomcatQ?br />4、修改连接池配置Qjira默认使用HSQLDBQ修?JIRA_HOME%\conf\server.xmlQ?br />该文g中的q接池配|更改ؓmysql的配|。如Q?br />1 username="root" 2 password="" 3 driverClassName="com.mysql.jdbc.Driver" 4 url="jdbc:mysql://localhost/jira?useUnicode=true & characterEncoding=utf-8"
注:一定要加:useUnicode=true & amp;characterEncoding=utf-8Qƈ在c:\WINDOWS\my.iniQmysql配置文gQ中的[mysqld]部分加入Qdefault-character-set=UTF8Q即讄mysql的默认字W集为UTF8Q,否则有ؕ码?br /> 5、修?JIRA_HOME%\atlassian-jira\WEB-INF\classes\entityengine.xml文gQ查找:<datasource name="defaultDS" field-type-name="hsql" helper-class="org.ofbiz.core.entity.GenericHelperDAO" hsql更改为:mysql?br /> 6、运?JIRA_HOME%\bin\startup.batQ输入:http://localhost:8080Q看到jira的安装向|安装成功?br /> 注: aQ将mysql5的jdbc驱动Qmysql-connector-java-5.0.5-bin.jar攑ֈ%JIRA_HOME%\common\lib目录下?br />bQmysql的安装参见:http://www.aygfsteel.com/wiflish/archive/2006/12/26/90123.html cQ由于jira是收费的Q启动jira自带的tomcatQ进入安装向导后Q需要输入注册码?br /> ]]> java~译和运行小工具 http://www.aygfsteel.com/wiflish/archive/2007/03/07/102418.html想飞的鱼 想飞的鱼 Wed, 07 Mar 2007 07:47:00 GMT http://www.aygfsteel.com/wiflish/archive/2007/03/07/102418.html http://www.aygfsteel.com/wiflish/comments/102418.html http://www.aygfsteel.com/wiflish/archive/2007/03/07/102418.html#Feedback 0 http://www.aygfsteel.com/wiflish/comments/commentRss/102418.html http://www.aygfsteel.com/wiflish/services/trackbacks/102418.html ~译和运行javaE序的DOS批处理文件?br />java初学者编写测试代码时Q不用专门开个dosH口Q输入命令来~译和运行javaE序?br />待~译的java文g拖动到compile.bat上,p~译Q?br />待q行的class文g拖动到run.bat上,pq行?br />点击下蝲
]]> 【{】JAVA的内省(introspectorQ与反射QreflectionQ?/title> http://www.aygfsteel.com/wiflish/archive/2007/03/05/101964.html想飞的鱼 想飞的鱼 Mon, 05 Mar 2007 09:40:00 GMT http://www.aygfsteel.com/wiflish/archive/2007/03/05/101964.html http://www.aygfsteel.com/wiflish/comments/101964.html http://www.aygfsteel.com/wiflish/archive/2007/03/05/101964.html#Feedback 1 http://www.aygfsteel.com/wiflish/comments/commentRss/101964.html http://www.aygfsteel.com/wiflish/services/trackbacks/101964.html
很多朋友在深入的接触
JAVA
语言后就会发现这样两个词Q反?/span>
(Reflection)
和内?/span>
(Introspector)
Q经常搞不清楚这到底是怎么回事Q在什么场合下应用以及如何使用Q今天把q二者放在一起介l,因ؓ它们二者是相辅相成的?/span>
反射
相对而言Q反比内省更容易理解一炏V用一句比较白的话来概括,反射是让你可以通过名称来得到对?/span>
(
c,属性,Ҏ
)
的技术。例如我们可以通过cd来生成一个类的实例;知道了方法名Q就可以调用q个ҎQ知道了属性名可以访问这个属性的倹{?/span>
q是写两个例子让大家更直观的了解反射的用方法:
//
通过cd来构造一个类的实?br />
Class cls_str = Class.forName(
"java.lang.String"
);
//
上面q句很眼熟,因ؓ使用q?/span>
JDBC
讉K数据库的人都用过
J
Object str = cls_str.newInstance();
//
相当?/span>
String str = new String();
//
通过Ҏ名来调用一个方?br />
String methodName =
"length"
;
Method m = cls_str.getMethod(methodName,
null
);
System.out.println(
"length is "
+ m.invoke(str,
null
));
//
相当?/span>
System.out.println(str.length());
上面的两个例子是比较常用Ҏ。看C面的例子有发问了:Z么要q么ȝ呢?本来一条语句就完成的事情干吗要整这么复杂?没错Q在上面的例子中实没有必要q么ȝ。不q你惛_q样一个应用程序,它支持动态的功能扩展Q也是说程序不重新启动但是可以自动加蝲新的功能Q这个功能用一个具体类来表C。首先我们必Mؓq些功能定义一个接口类Q然后我们要求所有扩展的功能cdd现我指定的接口,q个规定了应用程序和可扩展功能之间的接口规则Q但是怎么动态加载呢Q我们必让应用E序知道要扩展的功能cȝcdQ比如是
test.Func1
Q当我们把这个类?/span>
(
字符?/span>
)
告诉应用E序后,它就可以使用我们W一个例子的Ҏ来加载ƈ启用新的功能。这是cȝ反射Q请问你有别的选择吗?
关于Ҏ的反徏议大家看我的另外一文章?/span>
利用
Turbine
的事件映来扩展
Struts
的功?/span>
》,地址是:
http://www.javayou.com/article/CSDN/extend_struts.html
。这文章详l介l了如果通过反射来扩?/span>
Struts
框架的功能?/span>
内省
内省?/span>
Java
语言?/span>
Bean
cd性、事件的一U缺省处理方法。例如类
A
中有属?/span>
name,
那我们可以通过
getName,setName
来得到其值或者设|新的倹{通过
getName/setName
来访?/span>
name
属性,q就是默认的规则?/span>
Java
中提供了一?/span>
API
用来讉K某个属性的
getter/setter
ҎQ通过q些
API
可以使你不需要了解这个规则(但你最好还是要搞清楚)Q这?/span>
API
存放于包
java.beans
中?/span>
一般的做法是通过c?/span>
Introspector
来获取某个对象的
BeanInfo
信息Q然后通过
BeanInfo
来获取属性的描述器(
PropertyDescriptor
Q,通过q个属性描q器可以获取某个属性对应的
getter/setter
ҎQ然后我们就可以通过反射机制来调用这些方法。下面我们来看一个例子,q个例子把某个对象的所有属性名U和值都打印出来Q?/span>
/*
* Created on 2004-6-29
*/
package
demo;
import
java.beans.BeanInfo;
import
java.beans.Introspector;
import
java.beans.PropertyDescriptor;
/**
*
内省演示例子
*
@author
liudong
*/
public
class
IntrospectorDemo {
String name;
public
static
void
main(String[] args)
throws
Exception{
IntrospectorDemo demo =
new
IntrospectorDemo();
demo.setName(
"Winter Lau"
);
//
如果不想把父cȝ属性也列出来的话,
//
?/span>
getBeanInfo
的第二个参数填写父类的信?br />
BeanInfo bi = Introspector.getBeanInfo(demo.getClass(),
Object.
class
);
PropertyDescriptor[] props = bi.getPropertyDescriptors();
for
(
int
i=0;i<props.length;i++){
System.out.println(props[i].getName()+
"="
+
props[i].getReadMethod().invoke(demo,
null
));
}
}
public
String getName() {
return
name;
}
public
void
setName(String name) {
this
.name = name;
}
}
Web
开发框?/span>
Struts
中的
FormBean
是通过内省机制来将表单中的数据映射到类的属性上Q因此要?/span>
FormBean
的每个属性要?/span>
getter/setter
Ҏ。但也ƈ不Lq样Q什么意思呢Q就是说对一?/span>
Bean
cLԌ我可以没有属性,但是只要?/span>
getter/setter
Ҏ中的其中一个,那么
Java
的内省机制就会认为存在一个属性,比如cM有方?/span>
setMobile
Q那么就认ؓ存在一?/span>
mobile
的属性,q样可以方便我们?/span>
Bean
c通过一个接口来定义而不用去兛_具体实现Q不用去兛_
Bean
中数据的存储。比如我们可以把所有的
getter/setter
Ҏ攑ֈ接口里定义,但是真正数据的存取则是在具体cMd玎ͼq样可提高系l的扩展性?/span>
ȝ
?/span>
Java
的反以及内省应用到E序设计中去可以大大的提供程序的化和可扩展性。有很多目都是采取q两U技术来实现其核心功能,例如我们前面提到?/span>
Struts
Q还有用于处?/span>
XML
文g?/span>
Digester
目Q其实应该说几乎所有的目都或多或的采用q两U技术。在实际应用q程中二者要怺l合方能发挥真正的智能化以及高度可扩展性?/span>
]]> tomcat配置(提高q行效率) http://www.aygfsteel.com/wiflish/archive/2007/01/15/93970.html想飞的鱼 想飞的鱼 Mon, 15 Jan 2007 07:50:00 GMT http://www.aygfsteel.com/wiflish/archive/2007/01/15/93970.html http://www.aygfsteel.com/wiflish/comments/93970.html http://www.aygfsteel.com/wiflish/archive/2007/01/15/93970.html#Feedback 0 http://www.aygfsteel.com/wiflish/comments/commentRss/93970.html http://www.aygfsteel.com/wiflish/services/trackbacks/93970.html ?CATALINA_HOME%/conf/web.xml中有(以tomcat5.0.28Z)Q?/p>
1
<
servlet
>
2
<
servlet-name
>
jsp
</
servlet-name
>
3
<
servlet-class
>
org.apache.jasper.servlet.JspServlet
</
servlet-class
>
4
<
init-param
>
5
<
param-name
>
fork
</
param-name
>
6
<
param-value
>
false
</
param-value
>
7
</
init-param
>
8
<
init-param
>
9
<
param-name
>
xpoweredBy
</
param-name
>
10
<
param-value
>
false
</
param-value
>
11
</
init-param
>
12
<
load-on-startup
>
3
</
load-on-startup
>
13
</
servlet
>
在该D代码中增加Q?br /> 1 < servlet > 2 < servlet-name > jsp </ servlet-name > 3 < servlet-class > org.apache.jasper.servlet.JspServlet </ servlet-class > 4 < init-param > 5 < param-name > fork </ param-name > 6 < param-value > false </ param-value > 7 </ init-param > 8 < init-param > 9 < param-name > xpoweredBy </ param-name > 10 < param-value > false </ param-value > 11 </ init-param > 12 <!-- 增加的初始化参数 --> 13 < init-param > 14 < param-name > development </ param-name > 15 < param-value > false </ param-value > 16 </ init-param > 17 < load-on-startup > 3 </ load-on-startup > 18 </ servlet > development参数的说明: development Is Jasper used in development mode (will check for JSP modification on every access)? [true] 该参数默认gؓtrueQ即tomcat会对jsp面的每ơ访问都它是否发生了修改;该参数讄为false后,也就是说tomcat不以开发模式运行,即不再检jsp是否发生了修改,q样能提高运行效率?br />如果pȝq行后,偶尔Ҏ个jsp面q行了修改,只要删除该jsp面?CATALINA_HOME%/work目录中对应的servlet源文件和class文gQ再讉K该jsp面后,tomcat(jsp引擎)׃重新~译该jsp文g?br /> ]]> [转]关于文g下蝲的几个问题ȝ http://www.aygfsteel.com/wiflish/archive/2006/12/29/90670.html想飞的鱼 想飞的鱼 Fri, 29 Dec 2006 02:44:00 GMT http://www.aygfsteel.com/wiflish/archive/2006/12/29/90670.html http://www.aygfsteel.com/wiflish/comments/90670.html http://www.aygfsteel.com/wiflish/archive/2006/12/29/90670.html#Feedback 0 http://www.aygfsteel.com/wiflish/comments/commentRss/90670.html http://www.aygfsteel.com/wiflish/services/trackbacks/90670.html 转:http://ltc603.javaeye.com/blog/25158 使用servlet来下载文Ӟ其原理非常简单,只要得到文g的输入流Q或相应字节Q,然后写输出流卛_。现其中的几个l节问题展开Q? 1. MIMEcd的设|: Web 览器?MIME cd来识别非 HTML 文档Qƈ军_如何昄该文档内的数据? 例如EXCEL文g?MIME cd?"application/vnd.ms-excel "。要用servlet 来打开一?EXCEL 文档Q需要将 response 对象?header ?contentType 讄成“application/vnd.ms-excel ”? response.setContentType(contentType); 2. Content disposition HTTP response header中的content-disposition 允许 servlet 指定文档表示的信息。用这Uheader Q你可以将文档指定成单独打开Q而不是在览器中打开Q,q可以根据用L操作来显C? 如果用户要保存文档,你还可以文档一个文件名。这个徏议名UC出现?Save As 对话框的“文件名”栏中。如果没有指定,则对话框中就会出?servlet 的名字? servlet 中,?header 讄成下面这P response.setHeader("Content-disposition","attachment;filename="+ "Example.xls" );
response.setHeader("Content-Disposition", "inline; filename="fliename) 点击打开会在ie中打开?/p>
需要说明的有三点: Ø 中文文g名需要进行iso8859-1转码方可正确昄Q? fileName = new String(fileName.getBytes("GBK"),"iso8859-1"); Ø 传递的文g名,需要包含后~名(如果此文件有后缀名)Q否则丢失文件的属性,而不能自行选择相关E序打开? Ø 有下载前询问Q是打开文gq是保存到计机Q和通过IE览器直接选择相关应用E序插g打开两种方式Q前者如上代码所C,后者如下: response.setHeader("Content-disposition","filename="+ "Example.xls" ); 3. 在研I文件的上传及下载过E中Q有几点体会 E序的I/O操作往往是性能的瓶颈所在,java io定义了两个基本的抽象c?InputStream和OutputStream,对于不同的数据类型比如磁盘,|络又提供了不同的实玎ͼjava.io 也提供了一些缓冲流(BufferedStream)Qɼ盘可以很快的读写一大块的数? 而Java基本的I/OcMơ只能读写一个字?但缓冲流(BufferedStream)可以一ơ读写一Ҏ据,,~冲?Buffered Stream)大大提高了I/O的性能。所? Ø块块的读写数据会非常?因此,量大块的读写数? Ø使用BufferedInputStream和BufferedOutputStream来批处理数据以提高性能 Ø对象的序列化(serialization)非常影响I/O的性能,量用 注: 1、Servlet中输出流的简单处理方法:
// 得到当前web应用根目录下test.txt文g的实际物理\? String path = getServletContext().getRealPath( " /test.txt " ); OutputStream os = response.getOutputStream(); InputStream is = new FileInputStream(path); byte [] buff = new byte [ 1024 ]; int len; while ((len = is.read(buff)) != - 1 ) { os.write(buff, 0 , len); } is.close(); os.close();
2、输出流跟PrintWriter out = response.getWriter();不能同时使用?br />
]]> HTTP响应?/title> http://www.aygfsteel.com/wiflish/archive/2006/11/23/83082.html想飞的鱼 想飞的鱼 Thu, 23 Nov 2006 09:16:00 GMT http://www.aygfsteel.com/wiflish/archive/2006/11/23/83082.html http://www.aygfsteel.com/wiflish/comments/83082.html http://www.aygfsteel.com/wiflish/archive/2006/11/23/83082.html#Feedback 0 http://www.aygfsteel.com/wiflish/comments/commentRss/83082.html http://www.aygfsteel.com/wiflish/services/trackbacks/83082.html 1、response.setDateHeader("Expires", 0); 2、response.setHeader("Cache-Control", "no-cache"); 3、response.setHeader("Pragma", "no-cache"); 定时h当前面Q?br />response.setHeader("Refresh", "5"); //每隔5U刷Cơ当前页面?br />定时跌{面 response.setHeader("Refresh", "5; URL=http://www.google.com"); //5U后Q当前页面蟩转到google?br /> ]]> 使用jar命o创徏可执行的jar?/title> http://www.aygfsteel.com/wiflish/archive/2006/07/05/56672.html想飞的鱼 想飞的鱼 Wed, 05 Jul 2006 03:00:00 GMT http://www.aygfsteel.com/wiflish/archive/2006/07/05/56672.html http://www.aygfsteel.com/wiflish/comments/56672.html http://www.aygfsteel.com/wiflish/archive/2006/07/05/56672.html#Feedback 1 http://www.aygfsteel.com/wiflish/comments/commentRss/56672.html http://www.aygfsteel.com/wiflish/services/trackbacks/56672.html 1、创建可执行的jar包?br />手工写manifest.mf文g(jar命o自动生成的MANIFEST.MF文g中不会包含Main-Class属?QD例说明: 目录l构Q?br />mymanifest.mf //该文件可以随意放|?只要在执行jar命o时指定mymanifest.mf文g所在位|? - src - test Test. class
test.Test代码Q?br />1 package test; 2 public class Test { 3 public static void main(String[] args) { 4 System.out.println( " HelloWorld! " ); 5 } 6 }
mymanifest.mf文g内容Q?br />Manifest - Version: 1.0 // 该属性是创徏可执行jar包必需的,指定的Main-Class为全路径cdQ且该类必需有mainҎQ?/span>Main - Class: test.Test Created - By: wiflish
在src目录下执行: jar cvfm test.jar .. / mymanifest .
完成后会在src目录下生成一个test.jar文g。由于没有可视化界面Q双击test.jar会看到没反应?br />在命令行执行java -jar test.jar׃得到输出HelloWorld! q时完成了基本的创建可执行的jar包?br /> 2、创依赖其他包的可执行jar包?br />q时只要更改mymanifest.mf文g加入Q?br />Manifest - Version: 1.0 // 该属性是创徏可执行jar包必需的,指定的Main-Class为全路径cdQ且该类必需有mainҎQ?/span>Main - Class: test.Test // 该属性指定依赖包的\?路径是相对jar包所在\? Class - Path: lib / swing - layout - 1.0 .jar // q里举例说明Q随便用的包 Created - By: wiflish
目录l构Q?br />- src - test TestDepends. class //假设该类执行依赖?swing-layout-1.0.jarQ具体代码略?/span> testDepends .jar - lib swing - layout - 1.0 .jar
双击testDepends .jarp正确执行Q如?/span>TestDepends .jar包所在的当前目录下没有lib/swing-layout-1.0.jar的话Q如下目录结构:- src - test TestDepends. class // 假设该类执行依赖于 swing-layout-1.0.jarQ具体代码略?/span> testDepends.jar
双击testDepends.jar,会报Could not find the main class, Program will exit. 在命令行执行 java -jar testDepends.jar,׃得到找不到TestDepends.class中所依赖的类的错? ]]> jar命o中的MANIFEST文g属性列?/title> http://www.aygfsteel.com/wiflish/archive/2006/07/05/56659.html想飞的鱼 想飞的鱼 Wed, 05 Jul 2006 02:09:00 GMT http://www.aygfsteel.com/wiflish/archive/2006/07/05/56659.html http://www.aygfsteel.com/wiflish/comments/56659.html http://www.aygfsteel.com/wiflish/archive/2006/07/05/56659.html#Feedback 0 http://www.aygfsteel.com/wiflish/comments/commentRss/56659.html http://www.aygfsteel.com/wiflish/services/trackbacks/56659.html JAR File Specification MANIFEST.MF文g属性:Main Attributes
Main attributes are the attributes that are present in the main section
of the manifest. They fall into the following different groups:
Defines the manifest file version. The value is a legitimate version
number, as described in the above spec.
Created-By: Defines the version and the vendor of the java implementation on top
of which this manifest file is generated. This attribute is generated by
the jar tool.
Signature-Version: Defines the signature version of the jar file. The value should be
a valid version-number string.
Class-Path : The value of this attribute specifies the relative URLs of the extensions
or libraries that this application or extension needs. URLs are separated
by one or more spaces. The application or extension class loader uses the
value of this attribute to construct its internal search path.
attribute defined for stand-alone applications
This attribute is used by stand-alone applications that are bundled into
executable jar files which can be invoked by the java runtime directly
by running "java -jar x.jar ".
Main-Class : The value of this attribute defines the relative path of the main application
class which the launcher will load at startup time. The value must
not have the .class extension appended to the class
name.
attributes defined for applets
These attributes is used by an applet which is bundled into JAR files
to define requirements, version and location information for the extensions
which this applet depends on. (see Extension Versioning ).
Extension-List: This attribute indicates the extensions that are needed by the applet.
Each extension listed in this attribute will have a set of additional attributes
that the applet uses to specify which version and vendor of the extension
it requires.
<extension>-Extension-Name : This attribute is the unique name of the extension. The Java Plug-in
will compare the value of this attribute with the Extension-Name attribute
in the manifests of installed extensions to determine if the extension
is installed.
<extension>-Specification-Version This attribute specifies the minimum extension specification version
that is required by the applet. The Java Plug-in will compare the value
of this attribute with the Specification-Version attribute of the installed
extension to determine if the extension is up to date.
<extension>-Implementation-Version This attritute specifies the minimum extension implementation version
number that is required by the applet. The Java Plug-in will compare the
value of this attribute with the Implementation-Version attribute of the
installed extension to see if a more recent implementation needs to be
downloaded.
<extension>-Implementation-Vendor-Id This attribute can be used to identify the vendor of an extension implementation
if the applet requires an implementation from a specific vendor. The Java
Plug-in will compare the value of this attribute with the Implementation-Vendor-Id
attribute of the installed extension.
<extension>-Implementation-URL This attribute specifies a URL that can be used to obtain the most
recent version of the extension if the required version is not already
installed.
attribute defined for extension identification
This attribute is used by extensions to define their unique identity.
Extension-Name:
This attribute specifies a name for the extension contained in the Jar
file. The name should be a unique identifier such as the name of the main
package comprising the extension.
attributes defined for extension and package versioning
and sealing
information
These attributes define features of the extension which the JAR file is
a part of. The value of these attributes apply to all the packages in the
JAR file, but can be overridden by per-entry attributes.
Implementation-Title :
The value is a string that defines the title of the extension implementation.
Implementation-Version : The value is a string that defines the version of the extension implementation.
Implementation-Vendor : The value is a string that defines the organization that maintains
the extension implementation.
Implementation-Vendor-Id : The value is a string id that uniquely defines the organization that
maintains the extension implementation.
Implementation-URL : This attribute defines the URL from which the extension implementation
can be downloaded from.
Specification-Title : The value is a string that defines the title of the extension specification.
Specification-Version : The value is a string that defines the version of the extension specification.
Specification-Vendor : The value is a string that defines the organization that maintains
the extension specification.
Sealed : This attribute defines whether this JAR file is sealed or not. The
value can be either "true" or "false", case is ignored. If it is set to
"true", then all the packages in the JAR file are defaulted to be sealed,
unless they are defined otherwise individually. ]]> 通过java获取pȝ环境变量 http://www.aygfsteel.com/wiflish/archive/2006/07/03/56384.html想飞的鱼 想飞的鱼 Mon, 03 Jul 2006 09:11:00 GMT http://www.aygfsteel.com/wiflish/archive/2006/07/03/56384.html http://www.aygfsteel.com/wiflish/comments/56384.html http://www.aygfsteel.com/wiflish/archive/2006/07/03/56384.html#Feedback 0 http://www.aygfsteel.com/wiflish/comments/commentRss/56384.html http://www.aygfsteel.com/wiflish/services/trackbacks/56384.html 1 public static Map getEnv() { 2 Map map = new HashMap(); 3 String OS = System.getProperty( " os.name " ).toLowerCase(); 4 5 Process p = null ; 6 7 /** 8 * 以windowsZ. 9 */ 10 if (OS.indexOf( " windows " ) > - 1 ) { 11 try { 12 p = Runtime.getRuntime().exec( " cmd /c set " ); 13 BufferedReader br = new BufferedReader( new InputStreamReader(p.getInputStream())); 14 15 String line; 16 17 while ((line = br.readLine()) != null ) { 18 String[] str = line.split( " = " ); 19 map.put(str[ 0 ], str[ 1 ]); 20 } 21 } catch (IOException ioe) { 22 ioe.printStackTrace(); 23 } 24 } 25 return map; 26 }
上述代码windowspȝ中的环境变量转换为java的MapQ只要通过map.get(key)p得到环境变量|比如map.get("JAVA_HOME")Q得到JAVA_HOME的|即JAVA_HOME的系l\径?br /> 值得注意的是在java中用windows操作pȝ命o时要在命令前?u> cmd /c Q否则java会报?),错误列表如下Q?br /> 1 java.io.IOException: CreateProcess: ${执行的操作命令表辑ּ或?bat文g} error = 2 2 at java.lang.Win32Process.create(Native Method) 3 at java.lang.Win32Process. < init > (Win32Process.java: 63 ) 4 at java.lang.Runtime.execInternal(Native Method) 5 at java.lang.Runtime.exec(Runtime.java: 566 ) 6 at java.lang.Runtime.exec(Runtime.java: 428 ) 7 at java.lang.Runtime.exec(Runtime.java: 364 ) 8 at java.lang.Runtime.exec(Runtime.java: 326 ) 9 at org.apache.jsp.ChangeDirBajaRCXX_jsp._jspService(ChangeDirBaja 10 p.java: 185 )
该错误的解释Q?br />The error 2 comes from the CreateProcess() call, from MSDN (GetLastError(): 2 - The system cannot find the file specified. - ERROR_FILE_NOT_FOUND So, it means the path you passed cannot be found. Maybe you did not configure your Runtime class correctly. put the batch file in the same directory as the class file and use ( for a test):
]]>[转]java基本c装入异?/title> http://www.aygfsteel.com/wiflish/archive/2006/05/24/47837.html想飞的鱼 想飞的鱼 Wed, 24 May 2006 08:24:00 GMT http://www.aygfsteel.com/wiflish/archive/2006/05/24/47837.html http://www.aygfsteel.com/wiflish/comments/47837.html http://www.aygfsteel.com/wiflish/archive/2006/05/24/47837.html#Feedback 0 http://www.aygfsteel.com/wiflish/comments/commentRss/47837.html http://www.aygfsteel.com/wiflish/services/trackbacks/47837.html
原文链接Qhttp://www-128.ibm.com/developerworks/cn/java/j-dclp2.html
ClassNotFoundException
ClassNotFoundException
是最常见的类装入异常cd。它发生在装入阶DcJava 规范?ClassNotFoundException
的描q是q样的:
当应用程序试N过cȝ字符串名Uͼ使用以下三种Ҏ装入c,但却找不到指定名U的cd义时抛出该异常?/p>
c?Class
中的 forName()
Ҏ?/li>
c?ClassLoader
中的 findSystemClass()
Ҏ?/li>
c?ClassLoader
中的 loadClass()
Ҏ?/li>
所以,如果昑ּ地装入类的尝试失败,那么抛?ClassNotFoundException
。清?1 中的试用例提供的示例代码抛Z一?ClassNotFoundException
Q?/p>
清单 1. ClassNotFoundExceptionTest.java
import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; public class ClassNotFoundExceptionTest { public static void main(String args[]) { try { URLClassLoader loader = new URLClassLoader(new URL[] { new URL( "file://C:/CL_Article/ClassNotFoundException/")}); loader.loadClass("DoesNotExist"); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } } }
q个试用例定义了一个类装入器(MyClassLoader
Q,用于装入一个不存在的类Q?code>DoesNotExistQ。当它运行时Q会出现以下异常Q?/p>
java.lang.ClassNotFoundException: DoesNotExist at java.net.URLClassLoader.findClass(URLClassLoader.java:376) at java.lang.ClassLoader.loadClass(ClassLoader.java:572) at java.lang.ClassLoader.loadClass(ClassLoader.java:504) at ClassNotFoundExceptionTest.main(ClassNotFoundExceptionTest.java:11)
因ؓq个试试图使用?loadClass()
的显式调用来q行装入Q所以抛?ClassNotFoundException
?/p>
通过抛出 ClassNotFoundException
Q类装入器提C,定义cL所需要的字节码在c装入器所查找的位|上不存在。这些异怿复v来通常比较单。可以用 IBM ?verbose 选项查类路径Q确保用的c\径设|正(要获?verbose 的更多信息,请参阅本pd?W一文?/a>Q。如果类路径讄正确Q但是仍然看到这个错误,那么是需要的cdc\径中不存在。要修复q个问题Q可以把cȝ动到c\径中指定的目录或 JAR 文g中,或者把cL在的位置d到类路径中?/p>
NoClassDefFoundError
NoClassDefFoundError
是类装入器在装入阶段抛出的另一个常见异常。JVM 规范?NoClassDefFoundError
的定义如下:
如果 Java 虚拟机或 ClassLoader
实例试图装入cd义(作ؓ正常的方法调用的一部分Q或者作Z?new 表达式创建新实例的一部分Q,但却没有扑ֈcd义时抛出该异常?
当目前执行的cdl编译,但是找不到它的定义时Q会存在 searched-for cd义?
实际上,q意味着 NoClassDefFoundError
的抛出,是不成功的隐式类装入的结果?/p>
清单 2 到清?4 的测试用例生了 NoClassDefFoundError
Q因为类 B
的隐式装入会p|Q?/p>
清单 2. NoClassDefFoundErrorTest.java
public class NoClassDefFoundErrorTest { public static void main(String[] args) { A a = new A(); } }
清单 3. A.java
public class A extends B { }
清单 4. B.java
q几个清单中的代码编译好之后Q删?B
的类文g。当代码执行Ӟ׃出现以下错误Q?/p>
Exception in thread "main" java.lang.NoClassDefFoundError: B at java.lang.ClassLoader.defineClass0(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:810) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:147) at java.net.URLClassLoader.defineClass(URLClassLoader.java:475) at java.net.URLClassLoader.access$500(URLClassLoader.java:109) at java.net.URLClassLoader$ClassFinder.run(URLClassLoader.java:848) at java.security.AccessController.doPrivileged1(Native Method) at java.security.AccessController.doPrivileged(AccessController.java:389) at java.net.URLClassLoader.findClass(URLClassLoader.java:371) at java.lang.ClassLoader.loadClass(ClassLoader.java:572) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:442) at java.lang.ClassLoader.loadClass(ClassLoader.java:504) at NoClassDefFoundErrorTest.main(NoClassDefFoundErrorTest.java:3)
c?A
扩展了类 B
Q所以,当类 A
装入Ӟc装入器会隐式地装入c?B
。因为类 B
不存在,所以抛?NoClassDefFoundError
。如果显式地告诉c装入器装入c?B
Q例如通过 loadClass("B")
调用Q,那么׃抛出 ClassNotFoundException
?/p>
昄Q要修复q个ҎCZ中的问题Q在对应的类装入器的c\径中Q必d在类 B
。这个示例看h可能价g大、也不真实,但是Q在复杂的有许多cȝ真实pȝ中,会因为类在打包或部v期间的遗p发生这cLc?/p>
在这个例子中Q?code>A 扩展?B
Q但是,即 A
用其他方式引?B
Q也会出现同L问题 —?例如Q以Ҏ参数引用或作为实例字Dc如果两个类之间的关pL引用关系而不是承关p,那么会在W一ơ?A
时抛出错误,而不是在装入 A
时抛出?/p>
ClassCastException
c装入器能够抛出的另一个异常是 ClassCastException
。它是在cd比较中发C兼容cd的时候抛出的。JVM 规范指定 ClassCastException
是:
该异常的抛出Q表明代码企图把对象的类型{换成一个子c,而该对象q不是这个子cȝ实例?
清单 5 演示的代码示例会产生一?ClassCastException
Q?/p>
清单 5. ClassCastException.java
public class ClassCastExceptionTest { public ClassCastExceptionTest() { } private static void storeItem(Integer[] a, int i, Object item) { a[i] = (Integer) item; } public static void main(String args[]) { Integer[] a = new Integer[3]; try { storeItem(a, 2, new String("abc")); } catch (ClassCastException e) { e.printStackTrace(); } } }
在清?5 中,调用?storeItem()
ҎQ用一?Integer
数组、一?int
和一个字W串作ؓ参数。但是在内部Q该Ҏ做了两g事:
隐式地把 String
对象cd转换?Object
cdQ用于参数列表)?/li>
昑ּ地把q个 Object
cd转换?Integer
cdQ在Ҏ定义中)?/li>
当程序运行时Q会出现以下异常Q?/p>
java.lang.ClassCastException: java.lang.String at ClassCastExceptionTest.storeItem(ClassCastExceptionTest.java:6) at ClassCastExceptionTest.main(ClassCastExceptionTest.java:12)
q个异常是由昑ּcd转换抛出的,因ؓ试用例试图把类型ؓ String
的东西{换成 Integer
?/p>
当检查对象(例如清单 5 中的 item
Qƈ把类型{换成目标c(Integer
Q时Q类装入器会查以下规则:
对于普通对象(非数l)Q?/b>对象必须是目标类的实例或目标cȝ子类的实例。如果目标类是接口,那么会把它当作实C该接口的一个子cR?br />
对于数组cdQ?/b>目标cdL数组cd?java.lang.Object
?code>java.lang.Cloneable ?java.io.Serializable
?/li>
如果q反了以上Q何一条规则,那么c装入器׃抛出 ClassCastException
。修复这cd常的最单方式就是仔l检查对象要转换到的cd是否W合以上提到的规则。在某些情况下,在做cd转换之前?instanceof
q行查是有意义的?/p>
UnsatisfiedLinkError
在把本机调用链接到对应的本机定义Ӟc装入器扮演着重要角色。如果程序试图装入一个不存在或者放错的本机库时Q在链接阶段的解析过E会发生 UnsatisfiedLinkError
。JVM 规范指定 UnsatisfiedLinkError
是:
对于声明?native
的方法,如果 Java 虚拟机找不到和它对应的本a定义Q就会抛异常?
当调用本机方法时Q类装入器会试装入定义了该Ҏ的本机库。如果找不到q个库,׃抛出q个错误?/p>
清单 6 演示了抛?UnsatisfiedLinkError
的测试用?Q?/p>
清单 6. UnsatisfiedLinkError.java
public class UnsatisfiedLinkErrorTest { public native void call_A_Native_Method(); static { System.loadLibrary("myNativeLibrary"); } public static void main(String[] args) { new UnsatisfiedLinkErrorTest().call_A_Native_Method(); } }
q段代码调用本机Ҏ call_A_Native_Method()
Q该Ҏ是在本机?myNativeLibrary
中定义的。因个库不存在,所以在E序q行时会发生以下错误Q?/p>
The java class could not be loaded. java.lang.UnsatisfiedLinkError: Can't find library myNativeLibrary (myNativeLibrary.dll) in sun.boot.library.path or java.library.path sun.boot.library.path=D:\sdk\jre\bin java.library.path= D:\sdk\jre\bin at java.lang.ClassLoader$NativeLibrary.load(Native Method) at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:2147) at java.lang.ClassLoader.loadLibrary(ClassLoader.java:2006) at java.lang.Runtime.loadLibrary0(Runtime.java:824) at java.lang.System.loadLibrary(System.java:908) at UnsatisfiedLinkErrorTest.<clinit>(UnsatisfiedLinkErrorTest.java:6)
本机库的装入p?System.loadLibrary()
Ҏ的类的类装入器启?—?在清?6 中,是 UnsatisfiedLinkErrorTest
的类装入器。根据用的c装入器Q会搜烦不同的位|:
对于?bootstrap c装入器装入的类Q搜?sun.boot.library.path
?/li>
对于由扩展类装入器装入的c,先搜?java.ext.dirs
Q然后是 sun.boot.library.path
Q然后是 java.library.path
?/li>
对于ql类装入器装入的c,搜烦 sun.boot.library.path
Q然后是 java.library.path
?/li>
在清?6 中,UnsatisfiedLinkErrorTest
cLql类装入器装入的。要装入所引用的本机库Q这个类装入器先查找 sun.boot.library.path
Q然后查?java.library.path
。因为在两个位置中都没有需要的库,所以类装入器抛?UnsatisfiedLinkageError
?/p>
一旦理解了库装入过E所涉及的类装入器,可以通过把库攑֜合适位|来解决q类问题?/p>
ClassCircularityError
JVM 规范指定 ClassCircularityError
的抛出条件是Q?/p>
cL接口׃是自q类或超接口而不能被装入?
q个错误是在链接阶段的解析过E中抛出的。这个错误有点奇怪,因ؓ Java ~译器不允许发生q种循环情况。但是,如果独立地编译类Q然后再把它们放在一P可能发生这个错误。请设想以下场景。首先,~译清单 7 和清?8 中的c:
清单 7. A.java
public class A extends B { }
清单 8. B.java
然后Q分别编译清?9 和清?10 中的c:
清单 9. A.java
清单 10. B.java
public class B extends A { }
最后,采用清单 7 的类 A
和清?10 的类 B
Qƈq行一个应用程序,试图装入 A
或?B
。这个情늜h可能不太可能Q但是在复杂的系l中Q在把不同部分放在一L时候,可能会发生类似的情况?/p>
昄Q要修复q个问题Q必避免@环的cdơ结构?/p>
ClassFormatError
JVM 规范指出Q抛?ClassFormatError
的条件是Q?/p>
负责指定所h的编译类或接口的二进制数据Ş式有误?
q个异常是在c装入的链接阶段的校验过E中抛出。如果字节码发生了更改,例如ȝ本号或次版本号发生了更改Q那么二q制数据的Ş式就会有误。例如,如果对字节码故意做了更改Q或者在通过|络传送类文g时现Z错误Q那么就可能发生q个异常?/p>
修复q个问题的惟一Ҏ是获得字节码的正确副本Q可能需要重新进行编译?/p>
ExceptionInInitializerError
Ҏ JVM 规范Q抛?ExceptionInInitializer
的情冉|Q?/p>
如果初始化器H然完成Q抛Z些异?E
Q而且 E
的类不是 Error
或者它的某个子c,那么׃创徏 ExceptionInInitializerError
cȝ一个新实例Qƈ?E
作ؓ参数Q用q个实例代替 E
?br />
如果 Java 虚拟囑ֈ建类 ExceptionInInitializerError
的新实例Q但是因为出?Out-Of-Memory-Error
而无法创建新实例Q那么就抛出 OutOfMemoryError
对象作ؓ代替?/li>
清单 8 中的代码抛出 ExceptionInInitializerError
Q?/p>
清单 8. ExceptionInInitializerErrorTest.java
public class ExceptionInInitializerErrorTest { public static void main(String[] args) { A a = new A(); } } class A { // If the SecurityManager is not turned on, a // java.lang.ExceptionInInitializerError will be thrown static { if(System.getSecurityManager() == null) throw new SecurityException(); } }
当静态代码块中发生异常时Q会被自动捕捉ƈ?ExceptionInInitializerError
包装该异常。在下面的输Z可以看到q点Q?/p>
Exception in thread "main" java.lang.ExceptionInInitializerError at ExceptionInInitializerErrorTest.main(ExceptionInInitializerErrorTest.java:3) Caused by: java.lang.SecurityException at A.<clinit>(ExceptionInInitializerErrorTest.java:12) ... 1 more
q个错误在类装入的初始化阶段抛出。修复这个错误的Ҏ是检查造成 ExceptionInInitializerError
的异常(在堆栈跟t的 Caused by:
下显C)q寻N止抛个异常的方式?/p>
]]> Google Web Toolkit http://www.aygfsteel.com/wiflish/archive/2006/05/22/47455.html想飞的鱼 想飞的鱼 Mon, 22 May 2006 06:12:00 GMT http://www.aygfsteel.com/wiflish/archive/2006/05/22/47455.html http://www.aygfsteel.com/wiflish/comments/47455.html http://www.aygfsteel.com/wiflish/archive/2006/05/22/47455.html#Feedback 0 http://www.aygfsteel.com/wiflish/comments/commentRss/47455.html http://www.aygfsteel.com/wiflish/services/trackbacks/47455.html Google Web Toolkit (GWT) is a Java software development framework that makes writing AJAX applications like Google Maps and Gmail
easy for developers who don't speak browser quirks as a second
language. Writing dynamic web applications today is a tedious and
error-prone process; you spend 90% of your time working around subtle
incompatabilities between web browsers and platforms, and JavaScript's
lack of modularity makes sharing, testing, and reusing AJAX components
difficult and fragile.
GWT lets you avoid many of these headaches while offering your users
the same dynamic, standards-compliant experience. You write your front
end in the Java programming language, and the GWT compiler converts your Java classes to browser-compliant JavaScript and HTML.
GWT website: http://code.google.com/webtoolkit/
]]> ant中宏定义例子 http://www.aygfsteel.com/wiflish/archive/2006/05/18/46856.html想飞的鱼 想飞的鱼 Thu, 18 May 2006 08:47:00 GMT http://www.aygfsteel.com/wiflish/archive/2006/05/18/46856.html http://www.aygfsteel.com/wiflish/comments/46856.html http://www.aygfsteel.com/wiflish/archive/2006/05/18/46856.html#Feedback 0 http://www.aygfsteel.com/wiflish/comments/commentRss/46856.html http://www.aygfsteel.com/wiflish/services/trackbacks/46856.html
一个ant中用于编译的宏定义例子: 1 < macrodef name = " compile " > 2 < attribute name = " module " /> 3 < attribute name = " additional.src.dirs " default = "" /> 4 < element name = " options " optional = " yes " /> 5 6 < sequential > 7 < echo > Compiling @{module} </ echo > 8 < mkdir dir = " ${build.dir}/@{module}/classes " /> 9 < mkdir dir = " ${test.dir}/@{module}/classes " /> 10 < javac srcdir = " ${src}/@{module};@{additional.src.dirs} " 11 destdir = " ${build.dir}/@{module}/classes " debug = " ${compile.debug} " 12 deprecation = " ${compile.deprecation} " optimize = " ${compile.optimize} " 13 classpathref = " @{module}.compile.classpath " > 14 < options /> 15 </ javac > 16 < javac srcdir = " test/@{module} " debug = " true " 17 destdir = " ${test.dir}/@{module}/classes " > 18 < classpath > 19 < path refid = " @{module}.test.classpath " /> 20 < path location = " ${build.dir}/@{module}/classes " /> 21 </ classpath > 22 < options /> 23 </ javac > 24 </ sequential > 25 </ macrodef > 调用宏代码: 1?/span>< compile module = " web " additional.src.dirs = " ${build.dir}/web/gen " /> 2?lt;compile module="dao"/>
]]> ant property标签_解 http://www.aygfsteel.com/wiflish/archive/2006/05/12/45814.html想飞的鱼 想飞的鱼 Fri, 12 May 2006 03:49:00 GMT http://www.aygfsteel.com/wiflish/archive/2006/05/12/45814.html http://www.aygfsteel.com/wiflish/comments/45814.html http://www.aygfsteel.com/wiflish/archive/2006/05/12/45814.html#Feedback 0 http://www.aygfsteel.com/wiflish/comments/commentRss/45814.html http://www.aygfsteel.com/wiflish/services/trackbacks/45814.html
Property讄属性的7U方法:
1、设|name和value属性|比如Q?lt;property name="srcdir" value="${basedir}/src"/> 2、设|name和refid属性|比如Q?lt;property name="srcpath" refid="dao.compile.classpath"/>Q其中 ?dao.compile.classpath在别的地方定义?br />3、设|name和location属性|比如Q?lt;property name="srcdir" location="src"/>Q即srcdir的D |ؓQ当前项目根目录?src目录?br />4、设|file属性|比如Q?lt;property file="build.properties"/>Q?导入build.properties属性文件中 的属性?br />5、设|resource属性|比如Q?lt;propety resource="build.properties"/>,导入build.properties属性文 件中的属性?br />6、设|url属性|比如Q?lt;property url="http://www.aygfsteel.com/wiflish/build.properties"/>,导 ?入http://www.aygfsteel.com/wiflish/build.properties属性文件中的属性倹{?br />7、设|环境变量,比如Q?lt;property environment="env"/>Q设|系l的环境变量为前~env. <property name="tomcat.home" value="${env.CATALINA_HOME}"/> 系l的tomcat安装目录讄刊W ?tomcat.home属性中?br /> ]]> Xdoclet的标{֏用法 http://www.aygfsteel.com/wiflish/archive/2006/05/11/45626.html想飞的鱼 想飞的鱼 Thu, 11 May 2006 03:43:00 GMT http://www.aygfsteel.com/wiflish/archive/2006/05/11/45626.html http://www.aygfsteel.com/wiflish/comments/45626.html http://www.aygfsteel.com/wiflish/archive/2006/05/11/45626.html#Feedback 2 http://www.aygfsteel.com/wiflish/comments/commentRss/45626.html http://www.aygfsteel.com/wiflish/services/trackbacks/45626.html Xdoclet的标{֏用法 ]]>
վ֩ģ壺
|
۳ |
ɽ |
ذ |
ˮ |
Ϻ |
|
|
|
|
ĵ |
|
|
ɽ |
|
н |
ϰˮ |
|
|
|
|
|
ϰˮ |
|
ຣʡ |
|
̶ |
㶫ʡ |
Զ |
|
ƺ |
|
֦ |
Ƽ |
Դ |
|
|
|
|
|
üɽ |