??xml version="1.0" encoding="utf-8" standalone="yes"?>日本婷婷久久久久久久久一区二区,自拍亚洲一区,动漫h在线观看http://www.aygfsteel.com/fjq639/archive/2005/12/26/25448.html黑石黑石Mon, 26 Dec 2005 07:46:00 GMThttp://www.aygfsteel.com/fjq639/archive/2005/12/26/25448.htmlhttp://www.aygfsteel.com/fjq639/comments/25448.htmlhttp://www.aygfsteel.com/fjq639/archive/2005/12/26/25448.html#Feedback0http://www.aygfsteel.com/fjq639/comments/commentRss/25448.htmlhttp://www.aygfsteel.com/fjq639/services/trackbacks/25448.html1、FACTORY?qMM不了请吃饭了,麦当劳的鸡翅和肯德基的鸡都是MM爱吃的东西,虽然口味有所不同Q但不管你带MM去麦当劳或肯德基Q只向服务员说“来四个鸡翅”就行了。麦当劳和肯德基是生鸡翅的Factory

  工厂模式Q客L和工厂类分开。消费者Q何时候需要某U品,只需向工厂请求即可。消费者无M改就可以接纳C品。缺Ҏ当品修ҎQ工厂类也要做相应的修改。如Q如何创建及如何向客L提供?

  2、BUILDER?MM最爱听的就是“我׃”这句话了,见到不同地方的MM,要能够用她们的方a跟她说这句话哦,我有一个多U语a译机,上面每种语言都有一个按键,见到MM我只要按对应的键Q它p够用相应的语a说出“我׃”这句话了,国外的MM也可以轻松搞掂,q就是我的“我׃”builder。(q一定比军在伊拉克用的译机好卖)

  建造模式:品的内部表象和品的生成q程分割开来,从而一个徏造过E生成具有不同的内部表象的品对象。徏造模式得品内部表象可以独立的变化Q客户不必知道品内部组成的l节。徏造模式可以强制实行一U分步骤q行的徏造过E?

  3、FACTORY METHOD?请MM去麦当劳吃汉堡,不同的MM有不同的口味Q要每个都记住是一件烦人的事情Q我一般采用Factory Method模式Q带着MM到服务员那儿Q说“要一个汉堡”,具体要什么样的汉堡呢Q让MM直接跟服务员说就行了?

  工厂Ҏ模式Q核心工厂类不再负责所有品的创徏Q而是具体创建的工作交给子类dQ成Z个抽象工厂角Ԍ仅负责给出具体工厂类必须实现的接口,而不接触哪一个品类应当被实例化q种l节?

  4、PROTOTYPE?跟MM用QQ聊天Q一定要说些深情的话语了Q我搜集了好多肉ȝ情话Q需要时只要copy出来攑ֈQQ里面p了,q就是我的情话prototype了。(100块钱一份,你要不要Q?

  原始模型模式Q通过l出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的Ҏ创徏出更多同cd的对象。原始模型模式允许动态的增加或减品类Q品类不需要非得有M事先定的等U结构,原始模型模式适用于Q何的{l构。缺Ҏ每一个类都必配备一个克隆方法?

  5、SINGLETON?俺有6个漂亮的老婆Q她们的老公都是我,我就是我们家里的老公SigletonQ她们只要说道“老公”,都是指的同一个hQ那是?刚才做了个梦啦,哪有q么好的?

  单例模式Q单例模式确保某一个类只有一个实例,而且自行实例化ƈ向整个系l提供这个实例单例模式。单例模式只应在有真正的“单一实例”的需求时才可使用?

      [b:9ceca65206]l构型模式[/b:9ceca65206]

  6、ADAPTER?在朋友聚会上到了一个美女SarahQ从香港来的Q可我不会说_语Q她不会说普通话Q只好求助于我的朋友kent了,他作为我和Sarah之间的AdapterQ让我和Sarah可以怺交谈?也不知道他会不会耍我)

  适配器(变压器)模式Q把一个类的接口变换成客户端所期待的另一U接口,从而原本因接口原因不匚w而无法一起工作的两个c能够一起工作。适配cd以根据参数返q一个合适的实例l客L?

  7、BRIDGE?早上到MMQ要说早上好Q晚上碰到MMQ要说晚上好Q碰到MMI了件新服Q要说你的服好漂亮哦,到MM新做的发型,要说你的头发好漂亮哦。不要问我“早上碰到MM新做了个发型怎么说”这U问题,自己用BRIDGEl合一下不p?

  桥梁模式Q将抽象化与实现化脱耦,使得二者可以独立的变化Q也是说将他们之间的强兌变成弱关联,也就是指在一个Y件系l的抽象化和实现化之间用组?聚合关系而不是承关p,从而两者可以独立的变化?

  8、COMPOSITE?Mary今天q生日。“我q生日,你要送我一件礼物。”“嗯Q好吧,d店,你自己挑。”“这件T恤挺漂亮Q买Q这条裙子好看,乎ͼq个包也不错Q买。”“喂Q买了三件了呀Q我只答应送一件礼物的哦。”“什么呀QT恤加裙子加包包,正好配成一套呀Q小姐,ȝ你包h。”“……”,MM都会用Composite模式了,你会了没有?

  合成模式Q合成模式将对象l织到树l构中,可以用来描述整体与部分的关系。合成模式就是一个处理对象的树结构的模式。合成模式把部分与整体的关系用树l构表示出来。合成模式得客L把一个个单独的成分对象和׃们复合而成的合成对象同{看待?

  9、DECORATOR?Maryq完轮到Sarlyq生日,q是不要叫她自己挑了Q不然这个月伙食费肯定玩完,拿出我去q在华山上照的照片Q在背面写上“最好的的礼物,是׃的Fita”,再到街上C品店买了个像框Q卖C品的MM也很漂亮哦)Q再N壁搞术设计的Mike设计了一个漂亮的盒子装v来……,我们都是DecoratorQ最l都在修饰我q个人呀Q怎么P看懂了吗Q?

  装饰模式Q装饰模式以对客L透明的方式扩展对象的功能Q是l承关系的一个替代方案,提供比承更多的灉|性。动态给一个对象增加功能,q些功能可以再动态的撤消。增加由一些基本功能的排列l合而生的非常大量的功能?

  10、FACADE?我有一个专业的Nikon相机Q我喜Ƣ自己手动调光圈、快门,q样照出来的照片才专业,但MM可不懂这些,教了半天也不会。幸好相机有Facade设计模式Q把相机调整到自动Q只要对准目标按快门p了,一切由相机自动调整Q这样MM也可以用q个相机l我拍张照片了?

  门面模式Q外部与一个子pȝ的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口,使得子系l更易于使用。每一个子pȝ只有一个门面类Q而且此门面类只有一个实例,也就是说它是一个单例模式。但整个pȝ可以有多个门面类?

  11、FLYWEIGHT?每天跟MM发短信,手指都篏MQ最q买了个新手机,可以把一些常用的句子存在手机里,要用的时候,直接拿出来,在前面加上MM的名字就可以发送了Q再不用一个字一个字敲了。共享的句子是FlyweightQMM的名字就是提取出来的外部特征Q根据上下文情况使用?

  享元模式QFLYWEIGHT在拳L赛中指最轻量U。n元模式以׃n的方式高效的支持大量的细_度对象。n元模式能做到׃n的关键是区分内蕴状态和外蕴状态。内蕴状态存储在享元内部Q不会随环境的改变而有所不同。外蕴状态是随环境的改变而改变的。外蕴状态不能媄响内蕴状态,它们是相互独立的。将可以׃n的状态和不可以共享的状态从常规cM区分开来,不可以׃n的状态从c里剔除出去。客L不可以直接创׃n的对象,而应当用一个工厂对象负责创׃n的对象。n元模式大q度的降低内存中对象的数量?

  12、PROXY?跟MM在网上聊天,一开头L“hi,你好?“你从哪儿来呀Q”“你多大了?”“n高多呀Q”这些话Q真烦hQ写个程序做为我的Proxy吧,凡是接收到这些话都设|好了自动的回答Q接收到其他的话时再通知我回{,怎么P酷吧?

  代理模式Q代理模式给某一个对象提供一个代理对象,q由代理对象控制Ҏ对象的引用。代理就是一个h或一个机构代表另一个h或者一个机构采取行动。某些情况下Q客户不x者不能够直接引用一个对象,代理对象可以在客户和目标对象直接起到中介的作用。客L分L不出代理主题对象与真实主题对象。代理模式可以ƈ不知道真正的被代理对象,而仅仅持有一个被代理对象的接口,q时候代理对象不能够创徏被代理对象,被代理对象必Lpȝ的其他角色代为创建ƈ传入?

      [b:9ceca65206]行ؓ模式[/b:9ceca65206]

  13、CHAIN OF RESPONSIBLEITY?晚上Mp课,Z好开溜坐C最后一排,哇,前面坐了好几个漂亮的MM哎,扑ּU条Q写上“Hi,可以做我的女朋友吗?如果不愿意请向前传”,U条׃个接一个的传上MQ糟p,传到W一排的MM把纸条传l老师了,听说是个老处奛_Q快?

  责Q链模式:在责任链模式中,很多对象由每一个对象对其下家的引用而接

  h形成一条链。请求在q个链上传递,直到链上的某一个对象决定处理此h。客户ƈ不知道链上的哪一个对象最l处理这个请求,pȝ可以在不影响客户端的情况下动态的重新l织铑֒分配责Q。处理者有两个选择Q承担责L者把责Q推给下家。一个请求可以最l不被Q何接收端对象所接受?

  14、COMMAND?俺有一个MM安得特别严,没法见面Q只好借助于她弟弟在我们俩之间传送信息,她对我有什么指C,写一张纸条让她弟弟带l我。这不,她弟弟又传送过来一个COMMANDQؓ了感谢他Q我请他吃了杂酱面Q哪知道他说Q“我同时l我姐姐三个h友送COMMANDQ就C最气Q才h吃面。”,

  命o模式Q命令模式把一个请求或者操作封装到一个对象中。命令模式把发出命o的责d执行命o的责d割开Q委z不同的对象。命令模式允许请求的一方和发送的一方独立开来,使得h的一方不必知道接收请求的一方的接口Q更不必知道h是怎么被接Ӟ以及操作是否执行Q何时被执行以及是怎么被执行的。系l支持命令的撤消?

  15、INTERPRETER?俺有一个《MM真经》,上面有各UMM的攻略,比如说去吃西的步骤、去看电qҎ{等Q跟MMU会Ӟ只要做一个InterpreterQ照着上面的脚本执行就可以了?

  解释器模式:l定一个语a后,解释器模式可以定义出其文法的一U表C,q同时提供一个解释器。客L可以使用q个解释器来解释q个语言中的句子。解释器模式描q怎样在有了一个简单的文法后,使用模式设计解释q些语句。在解释器模式里面提到的语言是指M解释器对象能够解释的Ml合。在解释器模式中需要定义一个代表文法的命ocȝ{l构Q也是一pd的组合规则。每一个命令对象都有一个解释方法,代表对命令对象的解释。命令对象的{l构中的对象的Q何排列组合都是一个语a?

  16、ITERATOR?我爱上了MaryQ不一切的向她求婚?

  MaryQ“想要我跟你l婚Q得{应我的条g?

  我:“什么条件我都答应,你说吧?

  MaryQ“我看上了那个一克拉的钻石?

  我:“我乎ͼ我买Q还有吗Q?

  MaryQ“我看上了湖边的那栋别墅?

  我:“我乎ͼ我买Q还有吗Q?

  MaryQ“我看上那辆法拉利跑车?

  我脑袋嗡的一壎ͼ坐在椅子上,一咬牙Q“我乎ͼ我买Q还有吗Q?

  …?

  q代子模式:q代子模式可以顺序访问一个聚集中的元素而不必暴露聚集的内部表象。多个对象聚在一起Ş成的MUC集,聚集对象是能够包容一l对象的容器对象。P代子模式P代逻辑装C个独立的子对象中Q从而与聚集本n隔开。P代子模式化了聚集的界面。每一个聚集对象都可以有一个或一个以上的q代子对象,每一个P代子的P代状态可以是彼此独立的。P代算法可以独立于聚集角色变化?

  17、MEDIATOR?四个MM打麻,怺之间谁应该给谁多钱不清楚了,q怺当时我在旁边Q按照各自的{码数算钱,赚了q从我q里拿,赔了q也付l我Q一切就OK啦,俺得C四个MM的电话?

  调停者模式:调停者模式包装了一pd对象怺作用的方式,使得q些对象不必怺明显作用。从而他们可以松散偶合。当某些对象之间的作用发生改变时Q不会立卛_响其他的一些对象之间的作用。保证这些作用可以彼此独立的变化。调停者模式将多对多的怺作用转化Z对多的相互作用。调停者模式将对象的行为和协作抽象化,把对象在尺度的行ؓ上与其他对象的相互作用分开处理?

  18、MEMENTO?同时跟几个MM聊天Ӟ一定要记清楚刚才跟MM说了些什么话Q不然MM发现了会不高兴的哦,q怺我有个备忘录Q刚才与哪个MM说了什么话我都拯一份放到备忘录里面保存Q这样可以随时察看以前的记录啦?

  备忘录模式:备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏装的条件下Q将一个对象的状态捉住,q外部化Q存储v来,从而可以在来合适的时候把q个对象q原到存储v来的状态?

  19、OBSERVER?想知道咱们公司最新MM情报吗?加入公司的MM情报邮gl就行了Qtom负责搜集情报Q他发现的新情报不用一个一个通知我们Q直接发布给邮gl,我们作ؓ订阅者(观察者)可以及时收到情报啦

  观察者模式:观察者模式定义了一U一队多的依赖关p,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化Ӟ会通知所有观察者对象,使他们能够自动更新自己?

  20、STATE?跟MM交往Ӟ一定要注意她的状态哦Q在不同的状态时她的行ؓ会有不同Q比如你U她今天晚上ȝ电媄Q对你没兴趣的MM׃说“有事情啦”,对你不讨厌但q没喜欢上的MM׃说“好啊,不过可以带上我同事么Q”,已经喜欢上你的MM׃说“几炚wQ看完电影再L吧怎么P”,当然你看电媄q程中表现良好的话,也可以把MM的状态从不讨厌不喜欢变成喜欢哦?

  状态模式:状态模式允怸个对象在其内部状态改变的时候改变行为。这个对象看上去象是改变了它的类一栗状态模式把所研究的对象的行ؓ包装在不同的状态对象里Q每一个状态对象都属于一个抽象状态类的一个子cR状态模式的意图是让一个对象在其内部状态改变的时候,其行Z随之改变。状态模式需要对每一个系l可能取得的状态创立一个状态类的子cR当pȝ的状态变化时Q系l便改变所选的子类?

  21、STRATEGY?跟不同类型的MMU会Q要用不同的{略Q有的请电媄比较好,有的则去吃小吃效果不错,有的LvҎ漫最合适,单目的都是ؓ了得到MM的芳心,我的qMM锦囊中有好多Strategy哦?

  {略模式Q策略模式针对一l算法,每一个算法封装到h共同接口的独立的cMQ从而得它们可以相互替换。策略模式得算法可以在不媄响到客户端的情况下发生变化。策略模式把行ؓ和环境分开。环境类负责l持和查询行为类Q各U算法在具体的策略类中提供。由于算法和环境独立开来,法的增减,修改都不会媄响到环境和客L?

  22、TEMPLATE METHOD??看过《如何说服女生上床》这部经典文章吗Q女生从认识C床的不变的步骤分为y遇、打破僵局、展开q求、接吅R前戏、动手、爱抚、进d大步?Template method)Q但每个步骤针对不同的情况,都有不一L做法Q这p看你随机应变?具体实现)Q?

  模板Ҏ模式Q模板方法模式准备一个抽象类Q将部分逻辑以具体方法以及具体构造子的Ş式实玎ͼ然后声明一些抽象方法来q子类实现剩余的逻辑。不同的子类可以以不同的方式实现q些抽象ҎQ从而对剩余的逻辑有不同的实现。先制定一个顶U逻辑框架Q而将逻辑的细节留l具体的子类d现?

  23、VISITOR?情h节到了,要给每个MM送一束鲜花和一张卡片,可是每个MM送的花都要针对她个h的特点,每张卡片也要Ҏ个h的特Ҏ挑,我一个h哪搞得清楚,q是找花店老板和礼品店老板做一下VisitorQ让花店老板ҎMM的特炚w一束花Q让C品店老板也根据每个h特点选一张卡Q这样就L多了Q?

  讉K者模式:讉K者模式的目的是封装一些施加于某种数据l构元素之上的操作。一旦这些操作需要修改的话,接受q个操作的数据结构可以保持不变。访问者模式适用于数据结构相Ҏ定的pȝQ它把数据结构和作用于结构上的操作之间的耦合解脱开Q得操作集合可以相对自q演化。访问者模式得增加新的操作变的很ҎQ就是增加一个新的访问者类。访问者模式将有关的行为集中到一个访问者对象中Q而不是分散到一个个的节点类中。当使用讉K者模式时Q要尽可能多的对象览逻辑攑֜讉K者类中,而不是放到它的子cM。访问者模式可以跨q几个类的等U结构访问属于不同的{l构的成员类



黑石 2005-12-26 15:46 发表评论
]]>
设计模式的原??http://www.aygfsteel.com/fjq639/archive/2005/12/26/25447.html黑石黑石Mon, 26 Dec 2005 07:45:00 GMThttp://www.aygfsteel.com/fjq639/archive/2005/12/26/25447.htmlhttp://www.aygfsteel.com/fjq639/comments/25447.htmlhttp://www.aygfsteel.com/fjq639/archive/2005/12/26/25447.html#Feedback0http://www.aygfsteel.com/fjq639/comments/commentRss/25447.htmlhttp://www.aygfsteel.com/fjq639/services/trackbacks/25447.html   q年来,大家都开始注意设计模式。那么,到底我们Z么要用设计模式呢Q这么多设计模式Z么要q么设计呢?说实话,以前我还真没搞清楚。就是看大家一口一?Design pattern"Q心有点发虚。于是就C?四h?的设计模式,l果看得似懂非懂:看得时候好像是懂了Q过一会就忘了。可能是本h比较"愚钝"?))最q,有了Ҏ悟?独乐不如众乐"Q与大家分n一下,q望指教!
    Z么要提?Design Pattern"呢?Ҏ原因是ؓ了代码复用,增加可维护性。那么怎么才能实现代码复用呢?OO界有前辈的几个原则:"开Q闭"原则(Open Closed Principal)、里氏代换原则、合成复用原则。设计模式就是实Cq些原则Q从而达C代码复用、增加可l护性的目的?BR>

    一?开Q闭"原则


    此原则是?Bertrand Meyer"提出的。原文是Q?Software entities should be open for extension,but closed for modification"。就是说模块应对扩展开放,而对修改关闭。模块应量在不修改???Q指原来的代?代码的情况下q行扩展。那么怎么扩展呢?我们看工厂模?factory pattern":假设中关村有一个卖盗版盘和毛片的小子,我们l他设计一"光盘销售管理Y?。我们应该先设计一"光盘"接口。如图:
[pre]______________
|<<interface>>|
| 光盘        |
|_____________|
|+?)        |
|             |
|_____________|[/pre]
而盗版盘和毛片是其子cR小子通过"DiscFactory"来管理这些光盘。代码ؓQ?BR>
  1. public class DiscFactory{
  2.     public static 光盘 getDisc(String name){
  3.        return (光盘)Class.forName(name).getInstance();
  4.     }
  5. }
有h要买盗版盘,怎么实现呢?
  1. public class 子{
  2.     public static void main(String[] args){
  3.         光盘 d=DiscFactory.getDisc("盗版?);
  4.         光盘.?);
  5.     }
  6. }

    如果有一天,q小子良心发CQ开始卖正版软g。没关系Q我们只要再创徏一?光盘"的子c?正版软g"可以了。不需要修改原l构和代码。怎么PҎ展开发,对修改关闭?开-闭原?
    工厂模式是对具体产品q行扩展Q有的项目可能需要更多的扩展性,要对q个"工厂"也进行扩展,那就成了"抽象工厂模式"?BR>

    二、里氏代换原?/H3>
里氏代换原则是由"Barbara Liskov"提出的。如果调用的是父cȝ话,那么换成子类也完全可以运行。比如:
       光盘 d=new 盗版?);
       d.?);
    现在要将"盗版?cL?毛片"c,没问题,完全可以q行。Java~译E序会检查程序是否符合里氏代换原则。还记得javal承的一个原则吗Q子coverloadҎ的访问权限不能小于父cd应方法的讉K权限。比?光盘"中的Ҏ"?讉K权限?public"Q那?盗版??毛片"中的"?Ҏ׃能是package或privateQ编译不能通过。ؓ什么要q样呢?你想啊:如果"盗版???Ҏ是private。那么下面这D代码就不能执行了:
            光盘 d=new 盗版?);
            d.?);
可以_里氏代换原则是承复用的一个基?BR>

    三、合成复用原?/H3>
    是说要用l承Q多用合成关pL实现。我曄q样写过E序Q有几个c要与数据库打交道,写了一个数据库操作的类Q然后别的跟数据库打交道的类都承这个。结果后来,我修改了数据库操作类的一个方法,各个c都需要改动?牵一发而动全n"!面向对象是要把L动限制在量的范围?BR>

    在Java中,应尽量针对Interface~程Q而非实现cR这P更换子类不会影响调用它方法的代码。要让各个类可能少的跟别h联系Q?不要与陌生h说话"。这P城门qQ才不至于殃及池鱹{扩展性和l护性才能提?BR>
    理解了这些原则,再看设计模式Q只是在具体问题上怎么实现q些原则而已。张无忌学太极拳Q忘C所有招式,打倒了"玄幂二?Q所?心中无招"。设计模式可谓招敎ͼ如果先学通了各种模式Q又忘掉了所有模式而随心所Ԍ可谓OO之最高境界。呵呵,搞笑Q搞W!

q是我的一点心得,大家可能理解得更深刻。还望指教!

我的|站:http://albert.mycool.net
参考图书:《设计模式》、《Java与模式?img src ="http://www.aygfsteel.com/fjq639/aggbug/25447.html" width = "1" height = "1" />

黑石 2005-12-26 15:45 发表评论
]]>Java异常学习心得Q{Q?/title><link>http://www.aygfsteel.com/fjq639/archive/2005/12/22/25087.html</link><dc:creator>黑石</dc:creator><author>黑石</author><pubDate>Thu, 22 Dec 2005 07:42:00 GMT</pubDate><guid>http://www.aygfsteel.com/fjq639/archive/2005/12/22/25087.html</guid><wfw:comment>http://www.aygfsteel.com/fjq639/comments/25087.html</wfw:comment><comments>http://www.aygfsteel.com/fjq639/archive/2005/12/22/25087.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/fjq639/comments/commentRss/25087.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/fjq639/services/trackbacks/25087.html</trackback:ping><description><![CDATA[<P>本文重在Java中异常机制的一些概c写本文的目的在于方便我很长旉后若是忘了这些东西可以通过q片文章q速回忆v来?/P> <P>1. 异常机制<BR>1.1 异常机制是指当程序出现错误后Q程序如何处理。具体来_异常机制提供了程序退出的安全通道。当出现错误后,E序执行的流E发生改变,E序的控制权转移到异常处理器?BR>1.2 传统的处理异常的办法是,函数q回一个特D的l果来表C出现异常(通常q个Ҏl果是大家约定俗U的Q,调用该函数的E序负责查ƈ分析函数q回的结果。这样做有如下的弊端Q例如函数返?1代表出现异常Q但是如果函数确实要q回-1q个正确的值时׃出现hQ可L降低,程序代码与处理异常的代码؜爹在一Pp用函数的E序来分析错误,q就要求客户E序员对库函数有很深的了解?BR>1.3 异常处理的流E?BR>1.3.1 遇到错误Q方法立即结束,q不q回一个|同时Q抛Z个异常对?BR>1.3.2 调用该方法的E序也不会l执行下去,而是搜烦一个可以处理该异常的异常处理器Qƈ执行其中的代?/P> <P>2 异常的分c?BR>2.1 异常的分c?BR>2.1.1 异常的承结构:基类为ThrowableQError和Exceptionl承ThrowableQRuntimeException和IOException{承ExceptionQ具体的RuntimeExceptionl承RuntimeException?BR>2.1.2 Error和RuntimeException及其子类成ؓ未检查异常(uncheckedQ,其它异常成ؓ已检查异常(checkedQ?BR>2.2 每个cd的异常的特点<BR>2.2.1 Error体系<BR>ErrorcMpLqCJavaq行pȝ中的内部错误以及资源耗尽的情形。应用程序不应该抛出q种cd的对象(一般是p拟机抛出Q。如果出现这U错误,除了力使程序安全退出外Q在其他斚w是无能ؓ力的。所以,在进行程序设计时Q应该更xException体系?BR>2.2.2 Exception体系<BR>Exception体系包括RuntimeException体系和其他非RuntimeException的体p?BR>2.2.2.1 RuntimeException<BR>RuntimeException体系包括错误的类型{换、数l越界访问和试图讉KI指针等{。处理RuntimeException的原则是Q如果出现RuntimeExceptionQ那么一定是E序员的错误。例如,可以通过查数l下标和数组边界来避免数l越界访问异常?BR>2.2.2.2 其他QIOException{等Q?BR>q类异常一般是外部错误Q例如试图从文g֐d数据{,qƈ不是E序本n的错误,而是在应用环境中出现的外部错误?BR>2.3 与C++异常分类的不?BR>2.3.1 其实QJava中RuntimeExceptionq个cdLq不恰当Q因ZQ何异帔R是运行时出现的。(在编译时出现的错误ƈ不是异常Q换句话_异常是Z解决E序q行时出现的的错误)?BR>2.3.2 C++中logic_error与Java中的RuntimeException是等LQ而runtime_error与Java中非RuntimeExceptioncd的异常是{h的?/P> <P>3 异常的用方?BR>3.1 声明Ҏ抛出异常 <BR>3.1.1 语法QthrowsQ略Q?BR>3.1.2 Z么要声明Ҏ抛出异常Q?BR>Ҏ是否抛出异常与方法返回值的cd一样重要。假设方法抛出异常确没有声明该方法将抛出异常Q那么客L序员可以调用q个Ҏ而且不用~写处理异常的代码。那么,一旦出现异常,那么q个异常没有合适的异常控制器来解决?BR>3.1.3 Z么抛出的异常一定是已检查异常?<BR>RuntimeException与Error可以在Q何代码中产生Q它们不需要由E序员显C的抛出Q一旦出现错误,那么相应的异怼被自动抛出。而已查异常是q序员抛出的,q分ZU情况:客户E序员调用会抛出异常的库函数Q库函数的异常由库程序员抛出Q;客户E序员自׃用throw语句抛出异常。遇到ErrorQ程序员一般是无能为力的;遇到RuntimeExceptionQ那么一定是E序存在逻辑错误Q要对程序进行修改(相当于调试的一U方法)Q只有已查异常才是程序员所兛_的,E序应该且仅应该抛出或处理已查异常?BR>3.1.4 注意Q覆盖父cLҎ的子cL法不能抛出比父类Ҏ更多的异常,所以,有时设计父类的方法时会声明抛出异常,但实际的实现Ҏ的代码却q不抛出异常Q这样做的目的就是ؓ了方便子cL法覆盖父cL法时可以抛出异常?BR>3.2 如何抛出异常<BR>3.2.1 语法QthrowQ略Q?BR>3.2.2 抛出什么异常?<BR>对于一个异常对象,真正有用的信息时异常的对象类型,而异常对象本w毫无意义。比如一个异常对象的cd是ClassCastExceptionQ那么这个类名就是唯一有用的信息。所以,在选择抛出什么异常时Q最关键的就是选择异常的类名能够明说明异常情늚cR?BR>3.2.3 异常对象通常有两U构造函敎ͼ一U是无参数的构造函敎ͼ另一U是带一个字W串的构造函敎ͼq个字符串将作ؓq个异常对象除了cd名以外的额外说明?BR>3.2.4 创徏自己的异常:当Java内置的异帔R不能明确的说明异常情늚时候,需要创q异常。需要注意的是,唯一有用的就是类型名q个信息Q所以不要在异常cȝ设计上花费精力?BR>3.3 捕获异常<BR>如果一个异常没有被处理Q那么,对于一个非囑Ş界面的程序而言Q该E序会被中止q输出异怿息;对于一个图形界面程序,也会输出异常的信息,但是E序q不中止Q而是q回用户界面处理循环中?BR>3.3.1 语法Qtry、catch和finallyQ略Q?BR>控制器模块必ȝ接在try块后面。若掷出一个异常,异常控制机制会搜dC异常cd相符的第一个控制器随后它会q入那个catch 从句Qƈ认ؓ异常已得到控制。一旦catch 从句l束Ҏ制器的搜索也会停止?BR>3.3.1.1 捕获多个异常Q注意语法与捕获的顺序)Q略Q?BR>3.3.1.2 finally的用法与异常处理程Q略Q?BR>3.3.2 异常处理做什么?<BR>对于Java来说Q由于有了垃圾收集,所以异常处理ƈ不需要回收内存。但是依然有一些资源需要程序员来收集,比如文g、网l连接和囄{资源?BR>3.3.3 应该声明Ҏ抛出异常q是在方法中捕获异常Q?BR>原则Q捕捉ƈ处理哪些知道如何处理的异常,而传递哪些不知道如何处理的异?BR>3.3.4 再次抛出异常<BR>3.3.4.1 Z么要再次抛出异常Q?BR>在本U中Q只能处理一部分内容Q有些处理需要在更高一U的环境中完成,所以应该再ơ抛出异常。这样可以每的异常处理器处理它能够处理的异常?BR>3.3.4.2 异常处理程<BR>对应与同一try块的catch块将被忽略,抛出的异常将q入更高的一U?/P> <P>4 关于异常的其他问?BR>4.1 q度使用异常<BR>首先Q用异常很方便Q所以程序员一般不再愿意编写处理错误的代码Q而仅仅是单单的抛Z个异常。这样做是不对的Q对于完全已知的错误Q应该编写处理这U错误的代码Q增加程序的鲁棒性。另外,异常机制的效率很差?BR>4.2 异怸普通错误区分开<BR>对于普通的完全一致的错误Q应该编写处理这U错误的代码Q增加程序的鲁棒性。只有外部的不能定和预知的q行旉误才需要用异常?BR>4.3 异常对象中包含的信息<BR>一般情况下Q异常对象唯一有用的信息就是类型信息。但使用异常带字W串的构造函数时Q这个字W串q可以作为额外的信息。调用异常对象的getMessage()、toString()或者printStackTrace()Ҏ可以分别得到异常对象的额外信息、类名和调用堆栈的信息。ƈ且后一U包含的信息是前一U的集?/P><img src ="http://www.aygfsteel.com/fjq639/aggbug/25087.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/fjq639/" target="_blank">黑石</a> 2005-12-22 15:42 <a href="http://www.aygfsteel.com/fjq639/archive/2005/12/22/25087.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java中不同数据库q接字符?/title><link>http://www.aygfsteel.com/fjq639/archive/2005/12/21/24974.html</link><dc:creator>黑石</dc:creator><author>黑石</author><pubDate>Wed, 21 Dec 2005 09:42:00 GMT</pubDate><guid>http://www.aygfsteel.com/fjq639/archive/2005/12/21/24974.html</guid><wfw:comment>http://www.aygfsteel.com/fjq639/comments/24974.html</wfw:comment><comments>http://www.aygfsteel.com/fjq639/archive/2005/12/21/24974.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/fjq639/comments/commentRss/24974.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/fjq639/services/trackbacks/24974.html</trackback:ping><description><![CDATA[一.q接oracle数据?BR>    Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); <BR>    String url="jdbc:oracle:thin:@服务器ip:1521:数据库名U?;<BR>    Connection conn=DriverManager.getConnection(url,"用户?,"密码");<BR><BR>?q接mssql数据?BR><BR>     q接驱动文gjtds-0.6.jar<BR><BR>     String url="jdbc:jtds:sqlserver://localhost:1433/‘数据库名?Q?<BR>     自带驱动:<BR><BR>     Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();<BR>     String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs"; <BR><BR>?q接DB2数据?BR>     Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance(); <BR>     String url="jdbc:db2://localhost:5000/数据库名U?;<BR>四、jspq接Informix数据?BR><BR>      Class.forName("com.informix.jdbc.IfxDriver").newInstance(); <BR>      String url = "jdbc:informix-sqli://123.45.67.89:1533/testDB:INFORMIXSERVER=myserver; <BR>      user=testuser;password=testpassword"; <BR>     //testDBZ的数据库?<BR>     Connection conn= DriverManager.getConnection(url); <BR>     Statement stmt=conn.createStatement <BR><BR>五、jspq接<A target=_blank><FONT color=#3366cc>Sybase</FONT></A>数据?<BR><BR>    Class.forName("com.sybase.jdbc.SybDriver").newInstance(); <BR>   String url =" jdbc:sybase:Tds:localhost:5007/tsdata"; <BR>   //tsdataZ的数据库?<BR>   Properties sysProps = System.getProperties(); <BR>   SysProps.put("user","userid"); <BR>   SysProps.put("password","user_password"); <BR>   Connection conn= DriverManager.getConnection(url, SysProps); <BR><BR><BR>六、jspq接MySQL数据?nbsp;<BR>       Class.forName("org.gjt.mm.mysql.Driver").newInstance(); <BR>      String url ="jdbc:mysql://localhost/softforum? <BR><BR>      user=soft&password=soft1234&useUnicode=true&characterEncoding=8859_1" <BR>    //testDBZ的数据库?<BR>     Connection conn= DriverManager.getConnection(url); <BR><BR>未完待箋....<BR><BR><BR><BR><img src ="http://www.aygfsteel.com/fjq639/aggbug/24974.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/fjq639/" target="_blank">黑石</a> 2005-12-21 17:42 <a href="http://www.aygfsteel.com/fjq639/archive/2005/12/21/24974.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JVM内存试http://www.aygfsteel.com/fjq639/archive/2005/12/21/24965.html黑石黑石Wed, 21 Dec 2005 08:26:00 GMThttp://www.aygfsteel.com/fjq639/archive/2005/12/21/24965.htmlhttp://www.aygfsteel.com/fjq639/comments/24965.htmlhttp://www.aygfsteel.com/fjq639/archive/2005/12/21/24965.html#Feedback0http://www.aygfsteel.com/fjq639/comments/commentRss/24965.htmlhttp://www.aygfsteel.com/fjq639/services/trackbacks/24965.html
例子下蝲
默认的java虚拟机的大小比较,在对大数据进行处理时java׃报错Qjava.lang.OutOfMemoryError?/P>

讄jvm内存的方法,对于单独?classQ可以用下面的方法对Testq行时的jvm内存q行讄?BR>java -Xms64m -Xmx256m Test


默认的java虚拟机的大小比较,在对大数据进行处理时java׃报错Qjava.lang.OutOfMemoryError?/P>

讄jvm内存的方法,对于单独?classQ可以用下面的方法对Testq行时的jvm内存q行讄?BR>java -Xms64m -Xmx256m Test
-Xms是设|内存初始化的大?BR>-Xmx是设|最大能够用内存的大小Q最好不要超q物理内存大)

在weblogic中,可以在startweblogic.cmd中对每个domain虚拟内存的大进行设|,默认的设|是在commEnv.cmd里面?/P>

黑石 2005-12-21 16:26 发表评论
]]>
?Java 的注释上做文??http://www.aygfsteel.com/fjq639/archive/2005/12/21/24928.html黑石黑石Wed, 21 Dec 2005 04:15:00 GMThttp://www.aygfsteel.com/fjq639/archive/2005/12/21/24928.htmlhttp://www.aygfsteel.com/fjq639/comments/24928.htmlhttp://www.aygfsteel.com/fjq639/archive/2005/12/21/24928.html#Feedback0http://www.aygfsteel.com/fjq639/comments/commentRss/24928.htmlhttp://www.aygfsteel.com/fjq639/services/trackbacks/24928.html

目录

  前言
   一. Java 文?javadoc
   ? 文档注释的格?BR>     1. 文注释的格式化
     2. 文注释的三部分
   ? 使用 javadoc 标记
     http://outinn.diy.myrice.com/book/javadoc/#t31
     http://outinn.diy.myrice.com/book/javadoc/#t32
     http://outinn.diy.myrice.com/book/javadoc/#t33
  ? javadoc 命o


前言

  Java 的语法与 C++ 及ؓ怼Q那么,你知?Java 的注释有几种吗?是两U?

  // 注释一?BR>   /* ...... */ 注释若干?/P>

  不完全对Q除了以上两U之外,q有W三U,文档注释Q?/P>

  /** ...... */ 注释若干行,q写?javadoc 文

  通常q种注释的多行写法如下:

  /**
   * .........
   * .........
   */

  暂停Q暂停!q第三种注释有什么用Qjavadoc 又是什么东西?

  好,那就让我告诉你—?


一. Java 文?javadoc

  Java E序员都应该知道使用 JDK 开发,最好的帮助信息来?SUN 发布?Java 文。它分包、分c详l的提供了各Ҏ、属性的帮助信息Q具有详l的cL信息、烦引信息等Qƈ提供了许多相关类之间的关p,如ѝ实现接口、引用等?/P>

  Java 文档全是׃?html 文gl织h的,?SUM 的站点上可以下蝲它们的压~包。但是你肯定想不刎ͼq些文我们可以自己生成。——就此打住,再吊一ơ胃口?/P>

  安装?JDK 之后Q安装目录下有一?src.jar 文g或?src.zip 文gQ它们都是以 ZIP 格式压羃的,可以使用 WinZip 解压。解压之后,我们可以看到分目录攄全是 .java 文g。是了,q些是 Java q行cȝ源码了,非常完整Q连注释都写得一清二楚……不q,怎么看这些注释都有点似曾相识的感觉?

  q就不奇怪了Q我们的q底也快要揭开了。如果你仔细Ҏ一?.java 源文件中的文档注?(/** ... */) ?Java 文档的内容,你会发现它们是一L。Java 文档只是q在格式和排版上下了些功夫。再仔细一点,你会发现 .java 源文件中的注释还带有 HTML 标识Q如 <B>?lt;BR>?lt;Code> {,?Java 文档中,该出现这些标识的地方Q已l按标识的的定义q行了排版?/P>

  l于真像大白了,原来 Java 文是来自这些注释。难怪这些注释叫做文注释呢Q不q,是什么工hq些注释变成文的呢Q?/P>

  是该请出 javadoc 的时候了。在 JDK ?bin 目录下你可以扑ֈ javadocQ如果是 Windows 下的 JDKQ它的文件名?javadoc.exe。?javdoc ~译 .java 源文件时Q它会读?.java 源文件中的文档注释,q按照一定的规则?Java 源程序一赯行编译,生成文档?/P>

  介绍 javadoc 的编译命令之前,q是先了解一下文注释的格式吧。不qؓ了能够编译下面提到的若干例子Q这里先介绍一?javadoc 命oQ?/P>

  javadoc -d 文存放目录 -author -version 源文件名.java

  q条命o~译一个名?“源文g?java”的 java 源文Ӟq将生成的文存攑֜“文存攄录”指定的目录下,生成的文中 index.html 是文档的首c?author ?-version 两个选项可以省略?/P>


? 文注释的格?/B>

  文注释可以用于对类、属性、方法等q行说明。写文注释旉了需要?/** .... */ 限定之外Q还需要注意注释内部的一些细节问题?/P>

  1. 文和文档注释的格式?/P>

  生成的文是 HTML 格式Q而这?HTML 格式的标识符q不?javadoc 加的Q而是我们在写注释的时候写上去的。比如,需要换行时Q不是敲入一个回车符Q而是写入 <br>Q如果要分段Q就应该在段前写?<p>?/P>

  因此Q格式化文Q就是在文注释中添加相应的 HTML 标识?/P>

  文注释的正文ƈ不是直接复制到输出文?(文档?HTML 文g)Q而是d每一行后Q删掉前导的 * 号及 * 号以前的I格Q再输入到文的。如

  /**
* This is first line. <br>
***** This is second line. <br>
This is third line.
*/

  ~译输出后的 HTML 源码则是

  This is first line. <br>
This is second line. <br>
This is third line.

  前导?* 号允许连l用多个,其效果和使用一?* 号一P但多?* 号前不能有其它字W分隔,否则分隔W及后面?* 号都作为文档的内容? 号在q里是作为左边界使用Q如上例的第一行和W二行;如果没有前导?* P则边界从W一个有效字W开始,而不包括前面的空|如上例第三行?/P>

  q有一炚w要说明,文注释只说明紧接其后的cR属性或者方法。如下例Q?/P>
 
/** comment for class */
public class Test {

    /** comment for a attribute */
    int number;

    /** comment for a method */
    public void myMethod() { ...... }

    ......
}

  上例中的三处注释是分别对类、属性和Ҏ的文档注释。它们生成的文分别是说明紧接其后的cR属性、方法的。“紧接”二字尤光要,如果忽略了这一点,很可能造成生成的文错误。如

 
import java.lang.*;

/** commnet for class */

public class Test { ...... }

// 此例为正的例子

  q个文注释生成正的文。但只需要改变其中两行的位置Q变成下例,׃出错Q?/P>
 
/** commnet for class */

import java.lang.*;

public class Test { ...... }

// 此例为错误的例子

  q个例子只把上例?import 语句和文档注释部分交换了位置Q结果却大不相同——生成的文档中根本就找不Cq注释的内容了。原因何在?

  ?FONT color=#008000>/** commnet for class */”是?class Test 的说明,把它攑֜“public class Test { ...... }”之前时Q其后紧接着 class TestQ符合规则,所以生成的文正确。但是把它和“import java.lang.*;”调换了位置后,其后紧接的就是不 class Test 了,而是一?import 语句。由于文注释只能说明类、属性和ҎQimport 语句不在此列Q所以这个文档注释就被当作错误说明省略掉了?/P>

  2. 文档注释的三部分

  Ҏ在文中昄的效果,文档注释分ؓ三部分。先举例如下Q以便说明?/P>
 
/**
 * show Ҏ的简q?
 * <p>show Ҏ的详l说明第一?lt;br>
 * show Ҏ的详l说明第二行
 * @param b true 表示昄Qfalse 表示隐藏
 * @return 没有q回?
 */
public void show(boolean b) {
    frame.show(b);
}

  W一部分是简q。文档中Q对于属性和Ҏ都是先有一个列表,然后才在后面一个一个的详细的说明。列表中属性名或者方法名后面那段说明是q。如下图中被U框框选的部分Q?/P>

  q部分写在一D|档注释的最前面Q第一个点?(.) 之前 (包括点号)。换句话_是用第一个点号分隔文注释,之前是简qͼ之后是第二部分和W三部分。如上例中的 ? show Ҏ的简q?”?/P>

  有时Q即使正地以一个点号作为分隔,javadoc 仍然会出错,把点号后面的部分也做ZW一部分。ؓ了解册个问题,我们可以使用一?<p> 标志第二分部分开Z一D,如上例的? <p>show Ҏ的详l说明第一?....”。除此之外,我们也可以?<br> 来分隔?/P>

  W二部分是详l说明部分。该部分对属性或者方法进行详l的说明Q在格式上没有什么特D的要求Q可以包含若q个点号。它在文中的位|如下图所C:

  q部分文在上例中相应的代码是:

  * show Ҏ的简q?
   * <p>show Ҏ的详l说明第一?lt;br>
   * show Ҏ的详l说明第二行

  发现什么了Q对了,qC在其中。这一点要C了,不要画蛇添——在详细说明部分中再写一ơ简q哦Q?/P>

  W三部分是特D说明部分。这部分包括版本说明、参数说明、返回D明等。它在文中的位|:

  W三部分在上例中相应的代码是

  * @param b true 表示昄Qfalse 表示隐藏
   * @return 没有q回?/FONT>

  除了 @param ?@return 之外Q还有其它的一些特D标讎ͼ分别用于对类、属性和Ҏ的说明……不要推我,我马上就说?/P>


? 使用 javadoc 标记

  javadoc 标记是插入文注释中的特D标讎ͼ它们用于标识代码中的Ҏ引用。javadoc 标记由“@”及其后所跟的标记cd和专用注释引用组成。记住了Q三个部分——@、标记类型、专用注释引用。不q我宁愿把它分成两部分:@ 和标记类型、专用注释引用。虽?@ ?标记cd之间有时可以用空格符分隔Q但是我宁愿始终它们紧挨着写,以减出错机会?/P>

  javadoc 标记有如下一些:

标记 用于 作用
@author 对类的说?/TD> 标明开发该cL块的作?/TD>
@version 对类的说?/TD> 标明该类模块的版?/TD>
@see 对类、属性、方法的说明 参考{向,也就是相关主?/TD>
@param Ҏ法的说明 Ҏ法中某参数的说明
@return Ҏ法的说明 Ҏ法返回值的说明
@exception Ҏ法的说明 Ҏ法可能抛出的异常q行说明

  下面详细说明各标记?/P>

  1. @see 的?/P>

  @see 的句法有三种Q?

  @see cd
   @see #Ҏ名或属性名
   @see cd#Ҏ名或属性名

  cdQ可以根据需要只写出cd (?String) 或者写出类全名 (?java.lang.String)。那么什么时候只需要写出类名,什么时候需要写出类全名呢?

  如果 java 源文件中?import 语句包含了的c,可以只写出类名,如果没有包含Q则需要写出类全名。java.lang 也已l默认被包含了。这?javac ~译 java 源文件时的规定一P所以可以简单的?javac ~译来判断,源程序中 javac 能找到的c,javadoc 也一定能扑ֈQjavac 找不到的c,javadoc 也找不到Q这需要用类全名了?/P>

  Ҏ名或者属性名Q如果是属性名Q则只需要写出属性名卛_Q如果是Ҏ名,则需要写出方法名以及参数cdQ没有参数的ҎQ需要写ZҎ受如

成员cd 成员名称及参?/B> @see 句法
属?/TD> number @see number
属?/TD> count @see count
Ҏ count() @see count()
Ҏ show(boolean b) @see show(boolean)
Ҏ main(String[] args) @see main(String[])

  有时也可以偷懒:假如上例中,没有 count q一属性,那么参考方?count() 可以简写成 @see count。不q,Z安全赯Q还是写?@see count() 比较好?/P>

  @see 的第二个句法和第三个句法都是转向Ҏ或者属性的参考,它们有什么区别呢Q?/P>

  W二个句法中没有指出cdQ则默认为当前类。所以它定义的参考,都{向本cM的属性或者方法。而第三个句法中指ZcdQ则q可以{向其它类的属性或者方法?/P>

  关于 @see 标记Q我们D个例说明。由?@see 在对c说明、对属性说明、对Ҏ说明时用法都一P所以这里只以对c说明ؓ例?/P>
 
/**
 * @see String
 * @see java.lang.StringBuffer
 * @see #str
 * @see #str()
 * @see #main(String[])
 * @see Object#toString()
 */
public class TestJavaDoc {

}

  生成的文的相关部分如下图:

  String ?StringBuffer 都是?java.lang 包中Q由于这个包是默认导入了的,所以这两个cd以直接写cdQ也可以写类全名。str、str() 为同名属性和ҎQ所以方法名需要用 () 区分。main 是带参数的方法,所以在 () 中指明了参数cd。toString() 虽然在本cM也有 (?Object l承?Q但我们是想参?Object cȝ toString() ҎQ所以用了 Object#toString()?/P>

  奇怪的是,Z么其中只?str、str() ?main(String[]) 变成了链接呢Q那是因为编译时没有?java.lang 包或?Stirng、StringBuffer、Object 三个cȝ源文件一起加入编译,所以,生成的文没有关于那三个cȝ信息Q也׃可以建立链接了。后面讲?javadoc ~译命o的时候还会详l说明?/P>

  上例中如果去把类中的 str 属性去掉,那么生成的文又会有什么变化呢Q你会发玎ͼ原来?str, str()Q而现在变成了 str(), str()Q因?str 属性已l没有了Q所?str 也表C方?str()?/P>

  2. 使用 @author、@version 说明c?/P>

  q两个标记分别用于指明类的作者和版本。缺省情况下 javadoc 其忽略Q但命o行开?-author ?-version 可以修改q个功能Q其包含的信息被输出。这两个标记的句法如下:

  @author 作者名
   @version 版本?/FONT>

  其中Q@author 可以多次使用Q以指明多个作者,生成的文档中每个作者之间用逗号 (,) 隔开。@version 也可以用多ơ,只有W一ơ有效,生成的文档中只会昄W一ơ?@version 指明的版本号。如下例

 
/**
 * @author Fancy
 * @author Bird
 * @version Version 1.00
 * @version Version 2.00
 */
public class TestJavaDoc {

}

  生成文档的相关部分如图:

  从生成文档的囄中可以看出,两个 @author 语句都被~译Q在文中生成了作者列表。而两?@version 语句中只有第一句被~译了,只生成了一个版本号?/P>

  从图上看Q作者列表是以逗号分隔的,如果我想分行昄怎么办?另外Q如果我xCZ个以上的版本号又该怎么办?

  ——我们可以将上述两条 @author 语句合ؓ一句,把两?@version 语句也合Z句:

  @author Fancy<br>Bird
   @version Version 1.00<br>Version 2.00

  l果如图Q?/P>

  我们q样做即辑ֈ了目的,又没有破坏规则。@author 之后的作者名?@version 之后的版本号都可以是用户自己定义的Q?HTML 格式Q所以我们可以?<br> 标记其分行昄。同Ӟ在一?@version 中指明两个用 <br> 分隔的版本号Q也没有破坏只显C第一?@version 内容的规则?/P>

  3. 使用 @param、@return ?@exception 说明Ҏ

  q三个标记都是只用于Ҏ的。@param 描述Ҏ的参敎ͼ@return 描述Ҏ的返回|@exception 描述Ҏ可能抛出的异常。它们的句法如下Q?/P>

  @param 参数?参数说明
   @return q回D?BR>   @exception 异常cd 说明

  每一?@param 只能描述Ҏ的一个参敎ͼ所以,如果Ҏ需要多个参敎ͼ需要多ơ?@param 来描q?/P>

  一个方法中只能用一?@returnQ如果文说明中列了多个 @returnQ则 javadoc ~译时会发出警告Q且只有W一?@return 在生成的文档中有效?/P>

  Ҏ可能抛出的异常应当用 @exception 描述。由于一个方法可能抛出多个异常,所以可以有多个 @exception。每?@exception 后面应有q的异常cdQ说明中应指出抛出异常的原因。需要注意的是,异常cd应该Ҏ源文件的 import 语句定是写出类名还是类全名?  CZ如下Q?/P>
 
public class TestJavaDoc {

    /**
     * @param n a switch
     * @param b excrescent parameter
     * @return true or false
     * @return excrescent return
     * @exception java.lang.Exception throw when switch is 1
     * @exception NullPointerException throw when parameter n is null
     */
    public boolean fun(Integer n) throws Exception {
        switch (n.intValue()) {
        case 0:
            break;
        case 1:
            throw new Exception("Test Only");
        default:
            return false;
        }
        return true;
    }

}

  使用 javadoc ~译生成的文档相关部分如下图Q?/P>

  可以看到Q上例中 @param b excrescent parameter 一句是多余的,因ؓ参数只是一?nQƈ没有一?b?Q??javadoc ~译时ƈ没有查。因此,写文注释时一定要正确匚w参数表与Ҏ中正式参数表的项目。如果方法参数表中的参数?aQ文中却给出对参数 x 的解释,或者再多出一个参?iQ就会让人摸不着头脑了。@exceptin 也是一栗?/P>

  上例E序中ƈ没有抛出一?NullPointerExceptionQ但是文注释中Z么要写上q么一句呢Q难道又是ؓ了演C?q不是ؓ了演C描q多余的异常也能通过~译Q而是Z说明写异常说明时应考运行时 (RunTime) 异常的可能性。上例程序中Q如果参?n 是给的一个空?(null)Q那么程序会在运行的时候抛Z?NullPointerExceptionQ因此,在文注释中d了对 NullPointerException 的说明?/P>

  上例中的 @return 语句有两个,但是Ҏ规则Q同一个方法中Q只有第一?@return 有效Q其余的会被 javadoc 忽略。所以生成的文中没有出现第二个 @return 的描q?/P>

  讲到q里Q该怎么写文档注释你应该已经清楚了,下面开始讲?javadoc 的常用命令?/P>


? javadoc 命o

  q行 javadoc -help 可以看到 javadoc 的用法,q里列D常用参数如下Q?/P>

用法Q?BR>   javadoc [options] [packagenames] [sourcefiles]

选项Q?/P>
  -public 仅显C?public cd成员
  -protected 昄 protected/public cd成员 (~省)
  -package 昄 package/protected/public cd成员
  -private 昄所有类和成?/TD>
  -d <directory> 输出文g的目标目?/TD>
  -version 包含 @version D?/TD>
  -author 包含 @author D?/TD>
  -splitindex 烦引分为每个字母对应一个文?/TD>
  -windowtitle <text> 文档的浏览器H口标题

  javadoc ~译文档时可以给定包列表Q也可以l出源程序文件列表。例如在 CLASSPATH 下有两个包若q类如下Q?/P>

  fancy.Editor
   fancy.Test
   fancy.editor.ECommand
   fancy.editor.EDocument
   fancy.editor.EView

  q里有两个包 (fancy ?fancy.editor) ?5 个类。那么编译时 (Windows 环境) 可以使用如下 javadoc 命oQ?/P>

  javadoc fancy\Test.java fancy\Editor.java fancy\editor\ECommand.java fancy\editor\EDocument.java fancy\editor\EView.java

  q是l出 java 源文件作为编译参数的ҎQ注意命令中指出的是文g路径Q应该根据实际情冉|变。也可以是给出包名作为编译参敎ͼ如:

  javadoc fancy fancy.editor

  用浏览器打开生成文?index.html 文g卛_发现两种方式~译l果的不同,如下图:

  用第二条命o生成的文被框架分成了三部分Q包列表、类列表和类说明。在包列表中选择了某个包之后Q类列表中就会列包中的所有类Q在cd表中选择了某个类之后Q类说明部分׃昄cȝ详细文。而用W一条命令生成的文只有两部分,cd表和c说明,没有包列表。这是两种方式生成文的最大区别了?/P>

  下面再来l说选项?/P>

  -public?protected?package?private 四个选项Q只需要Q选其一卛_。它们指定的昄cL员的E度。它们显C的成员多少是一个包含的关系Q如下表Q?/P>
-private (昄所有类和成?
-package (昄 package/protected/public cd成员)
-protected (昄 protected/public cd成员)
-public (仅显C?public cd成员)

  -d 选项允许你定义输出目录。如果不?-d 定义输出目录Q生成的文档文g会放在当前目录下?d 选项的用法是

  -d 目录?/FONT>

  目录名ؓ必填,也就是说Q如果你使用?-d 参数Q就一定要为它指定一个目录。这个目录必dl存在了Q如果还不存在,请在q行 javadoc 之前创徏该目录?/P>

  -version ?-author 用于控制生成文时是否生?@version ?@author 指定的内宏V不加这两个参数的情况下Q生成的文中不包含版本和作者信息?/P>

  -splitindex 选项烦引分为每个字母对应一个文件。默认情况下Q烦引文件只有一个,且该文g中包含所有烦引内宏V当然生成文档内容不多的时候,q样做非常合适,但是Q如果文内定w常多的时候,q个索引文g包含非常多的内容,昑־q于庞大。?-splitindex 会把索引文g按各索引的W一个字母进行分c,每个字母对应一个文件。这P减M一个烦引文件的负担?/P>

  -windowtitle 选项为文档指定一个标题,该标题会昄在窗口的标题栏上。如果不指定该标题,而默认的文标题为“生成的文Q无标题Q”。该选项的用法是Q?/P>

  -windowtitle 标题

  标题是一串没有包含空格的文本Q因为空格符是用于分隔各参数的,所以不能包含空根{同 -d cMQ如果指定了 -windowtitle 选项Q则必须指定标题文本?/P>

  到此为止QJava 文档?javadoc ׃l完了。javadoc 真的能让我们?Java 注释上做文章——生成开发文?/P>

黑石 2005-12-21 12:15 发表评论
]]>
java中静态方法和非静态方法覆盖的区别http://www.aygfsteel.com/fjq639/archive/2005/12/21/24924.html黑石黑石Wed, 21 Dec 2005 03:16:00 GMThttp://www.aygfsteel.com/fjq639/archive/2005/12/21/24924.htmlhttp://www.aygfsteel.com/fjq639/comments/24924.htmlhttp://www.aygfsteel.com/fjq639/archive/2005/12/21/24924.html#Feedback0http://www.aygfsteel.com/fjq639/comments/commentRss/24924.htmlhttp://www.aygfsteel.com/fjq639/services/trackbacks/24924.html  首先我们提供两个c,基类?/FONT>ParentQ派生类?/FONT>Child。在Parent中我们提供两个方法,一个是静态方?/FONT>staticMethod(),一个是非静态方?/FONT>nonStaticMethod()。在Child

cM我们覆盖着两个Ҏ?

class Parent{

 public void nonStaticMethod() {

        System.out.println("Parent's Non-Static Method is Called");

  }  

       public static void staticMethod() { 

 System.out.println("parent's static method is called");  

}

}

class Child extends Parent{

 public void nonStaticMethod() { 

System.out.println("child's non-static method is called"); 

 } 

 public static void staticMethod() {

               System.out.println("child's static method is called"); 

     }  

}

?/FONT>TestcM我们分别使用Parent p1 = new Parent(),Parent p2 = new Child(),Child c = new Child() 得到三个实例Qƈ分别调用静态方法和非静态方法,我们来看E序的运行结?

?/FONT>TestcM我们分别使用Parent p1 = new Parent(),Parent p2 = new Child(),Child c = new Child()得到三个实例Qƈ分别调用静态方法和非静态方法,我们来看E序的运行结?

public class Test{

      public static void main(String args[])          {  

       Parent p1 = new Parent();  

        Parent p2 = new Child();  

       Child c = new Child();

      System.out.print("Parent.static: ");

                 Parent.staticMethod(); 

     System.out.print("p1.static: ");

p1.staticMethod(); 

         System.out.print("p2.static: ");

p2.staticMethod();

        System.out.print("p1.nonStatic: ");

        p1.nonStaticMethod();

        System.out.print("p2.nonStatic: ");

        p2.nonStaticMethod();

        System.out.print("Child.static: ");

Child.staticMethod();

      System.out.print("c.static: ");

                 c.staticMethod(); 

         System.out.print("c.nonStatic: ");

        c.nonStaticMethod(); 

      }

}

E序的运行结果ؓQ?

Parent.static: parent's static method is called

p1.static: parent's static method is called

p2.static: parent's static method is called

p1.nonStatic: Parent's Non-Static Method is Calle

p2.nonStatic: child's non-static method is called

Child.static: child's static method is called

c.static: child's static method is called

c.nonStatic: child's non-static method is called

值得注意的是p2实际上是一个Child的类型的引用Q然而在调用静态方法的时候,它执行的却是父类的静态方法,而不是Child的静态方法,而调?p2的非静态方法的时候执行的是Child 的非静态方法,Z么呢Q?FONT color=#ff0000>原因是静态方法是在编译的时候把静态方法和cȝ引用cdq行匚wQ而不是在q行的时候和cd用进行匹配。因此我们得出结论:当我们在子类中创建的静态方法,它ƈ不会覆盖父类中相同名字的静态方法?



黑石 2005-12-21 11:16 发表评论
]]>
理解构造器http://www.aygfsteel.com/fjq639/archive/2005/12/21/24920.html黑石黑石Wed, 21 Dec 2005 02:51:00 GMThttp://www.aygfsteel.com/fjq639/archive/2005/12/21/24920.htmlhttp://www.aygfsteel.com/fjq639/comments/24920.htmlhttp://www.aygfsteel.com/fjq639/archive/2005/12/21/24920.html#Feedback0http://www.aygfsteel.com/fjq639/comments/commentRss/24920.htmlhttp://www.aygfsteel.com/fjq639/services/trackbacks/24920.html

 要学习Java,你必ȝ解构造器。因为构造器可以提供许多Ҏ的方法,q个对于初学者经常؜淆。但是,构造器和方法又有很多重要的区别?BR>
     我们说构造器是一U方法,p讲澳大利亚的鸭嘴兽是一U哺育动物。(按:老外喜欢打比喻,我也q着译Q。要理解鸭嘴兽,那么先必ȝ解它和其他哺育动物的区别。同样地Q要理解构造器Q那么就要了解构造器和方法的区别。所有学习java的hQ尤其是寚w些要认证考试的,理解构造器是非帔R要的。下面将单介l一?Q最后用一个表作了些简单的ȝ?


一?FONT color=#0000ff>功能和作用的不同
构造器是ؓ了创Z个类的实例。这个过E也可以在创Z个对象的时候用刎ͼPlatypus p1 = new Platypus();

相反Q方法的作用是ؓ了执行java代码?

二、修饰符Q返回值和命名的不?/SPAN>
    构造器和方法在下面三个斚w的区别:修饰W,q回|命名。和Ҏ一P构造器可以有Q何访问的修饰Q?public, protected, private或者没有修饎ͼ通常被package ?friendly调用Q? 不同于方法的是,构造器不能有以下非讉K性质的修饎ͼ abstract, final, native, static, 或?synchronized?

q回cd也是非常重要的。方法能q回Mcd的值或者无q回|voidQ,构造器没有q回|也不需要void?

最后,谈谈两者的命名。构造器使用和类相同的名字,而方法则不同。按照习惯,Ҏ通常用小写字母开始,而构造器通常用大写字母开始。构造器通常是一个名词,因ؓ它和cd相同Q而方法通常更接q动词,因ؓ它说明一个操作?

三?this"的用?/SPAN>
     构造器和方法用关键字this有很大的区别。方法引用this指向正在执行Ҏ的类的实例。静态方法不能用this关键字,因ؓ静态方法不属于cȝ实例Q所以this也就没有什么东西去指向。构造器的this指向同一个类中,不同参数列表的另外一个构造器Q我们看看下面的代码Q?

public class Platypus {

String name;

Platypus(String input) {
  name = input;
}

Platypus() {
   this("John/Mary Doe");
}

  public static void main(String args[]) {
    Platypus p1 = new Platypus("digger");
   Platypus p2 = new Platypus();
  }
}

    在上面的代码中,?个不同参数列表的构造器。第一个构造器Q给cȝ成员name赋|W二个构造器Q调用第一个构造器Q给成员变量name一个初始?"John/Mary Doe".

在构造器中,如果要用关键字this,那么Q必L在第一行,如果不这P导致一个编译错误?

四?super"的用?
      构造器和方法,都用关键字super指向类Q但是用的方法不一栗方法用q个关键字去执行被重载的类中的Ҏ。看下面的例子:

class Mammal {
   void getBirthInfo() {
      System.out.println("born alive.");
   }
}

class Platypus extends Mammal {
   void getBirthInfo() {
     System.out.println("hatch from eggs");
     System.out.print("a mammal normally is ");
     super.getBirthInfo();
   }
}

在上面的例子中,使用super.getBirthInfo()去调用超cMammal中被重蝲的方法?

构造器使用super去调用超cM的构造器。而且q行代码必须攑֜W一行,否则~译出错。看下面的例子:

public class SuperClassDemo {
  SuperClassDemo() {}
}

class Child extends SuperClassDemo {
  Child() {
      super();
  }
}

在上面这个没有什么实际意义的例子中,构造器 Child()包含?super,它的作用是超cM的构造器SuperClassDemo实例化,q加?ChildcM?

五、编译器自动加入代码
     ~译器自动加入代码到构造器Q对于这个,javaE序员新手可能比较؜淆。当我们写一个没有构造器的类Q编译的时候,~译器会自动加上一个不带参数的构造器Q例如:public class Example {}
~译后将如下代码Q?

public class Example {
    Example() {}
}

在构造器的第一行,没有使用superQ那么编译器也会自动加上Q例如:

public class TestConstructors {
  TestConstructors() {}
}

~译器会加上代码Q如下:

public class TestConstructors {
  TestConstructors() {
    super();
  }
}

仔细想一下,q道下面的代码

public class Example {}

l过会被~译器加代码形如Q?

public class Example {
   Example() {
     super();
   }
}

六、?/SPAN>
    构造器是不能被l承的。子cd以承超cȝMҎ。看看下面的代码Q?

public class Example {
  public void sayHi {
    system.out.println("Hi");
  }

  Example() {}
}

public class SubClass extends Example {
}

c?SubClass 自动l承了父cM的sayHiҎQ但是,父类中的构造器 Example()却不能被l承?

ȝ

主题 构造器 Ҏ
功能 建立一个类的实? java功能语句
修饰 不能用bstract, final, native, static, or synchronized ?/TD>
q回cd 没有q回|没有void 有返回|或者void
命名 和类名相同;通常为名词,大写开?/TD> 通常代表一个动词的意思,写开?/TD>
this
指向同一个类中另外一个构造器Q在W一?
指向当前cȝ一个实例,不能用于静态方?/TD>
super 调用父类的构造器Q在W一?/TD>
调用父类中一个重载的Ҏ
l承 构造器不能被? Ҏ可以被?

~译器自动加入一个缺省的构造器
自动加入Q如果没有) 不支?
~译器自动加入一个缺省的调用到超cȝ构造器 自动加入Q指super(),如果没有Q?/TD> 不支?


黑石 2005-12-21 10:51 发表评论
]]>javacȝ初始化顺?/title><link>http://www.aygfsteel.com/fjq639/archive/2005/12/21/24904.html</link><dc:creator>黑石</dc:creator><author>黑石</author><pubDate>Wed, 21 Dec 2005 01:12:00 GMT</pubDate><guid>http://www.aygfsteel.com/fjq639/archive/2005/12/21/24904.html</guid><wfw:comment>http://www.aygfsteel.com/fjq639/comments/24904.html</wfw:comment><comments>http://www.aygfsteel.com/fjq639/archive/2005/12/21/24904.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/fjq639/comments/commentRss/24904.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/fjq639/services/trackbacks/24904.html</trackback:ping><description><![CDATA[<PRE>abstract class base { public int age=getNumber(100); static { System.out.println("base static block"); } { System.out.println("base nonstatic block"); } static int sage=getNumber(50); base() { System.out.println(age); System.out.println("base start"); draw();//会调用子c覆盖后的方? System.out.println("base end"); } static int getNumber(int base) { System.out.println("base.getNumber int"+base); return base; } public void draw() { System.out.println("base.draw"); } } public class initializeOrder extends base{ public int age=getNumber(1001); private int _radius=getNumber(10); static int sage=getNumber(250); static { System.out.println("subclass static block"); } { System.out.println("subclass nonstatic block"); } initializeOrder(int radius) { _radius=radius; System.out.println(age); System.out.println("initializeOrder initialized"); } public void draw() { System.out.println("initializeOrder.draw "+_radius); } /** *//** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub new initializeOrder(1000); } }<BR> q行l果Q?BR><BR>C:\java>java initializeOrder<BR>base static block<BR>base.getNumber int50<BR>base.getNumber int250<BR>subclass static block<BR>base.getNumber int100<BR>base nonstatic block<BR>100<BR>base start<BR>initializeOrder.draw 0<BR>base end<BR>base.getNumber int1001<BR>base.getNumber int10<BR>subclass nonstatic block<BR>1001<BR>initializeOrder initialized</PRE> <P>C:\java></P> <P>ȝQ?BR>1、类只有在用New调用创徏的时候才会被JAVAc装载器装入<BR>2、JAVAc首ơ装入时Q会寚w态成员变量或Ҏq行一ơ初始化,但方法不被调用是不会执行的,静态成员变量和静态初始化块别相同,非静态成员变量和非静态初始化块别相同?BR>先初始化父类的静态代?-->初始化子cȝ静态代?-><BR>初始化父cȝ非静态代?-->初始化父cL造函?--><BR>初始化子c非静态代?-->初始化子cL造函?BR>3、创建类实例Ӟ首先按照父子l承关系q行初始?BR>4、类实例创徏时候,首先初始化块部分先执行,然后是构造方法;然后?BR>本类l承的子cȝ初始化块执行Q最后是子类的构造方?BR>5、类消除时候,首先消除子类部分Q再消除父类部分<BR><STRONG>试:<BR><BR>package com.javabase;</STRONG></P> <P><STRONG>/**<BR> * <p>Title: qx例子练?lt;/p><BR> *<BR> * <p>Description: qx例子练?lt;/p><BR> *<BR> * <p>Copyright: Copyright (c) 2005</p><BR> *<BR> * <p>Company: 北京开元东方科技有限公司</p><BR> *<BR> * @author 樊徏?BR> * @version 1.0<BR> * 试javacd载初始化序<BR> */<BR>abstract class base<BR>{<BR>    public int age=getNumber(100);<BR>    static<BR>    {<BR>        System.out.println("base static block");<BR>    }<BR>    {<BR>        System.out.println("base nonstatic block");<BR>    }<BR>    static int sage=getNumber(50);<BR>    base()<BR>    {<BR>        System.out.println(age);<BR>        System.out.println("base start");<BR>        draw();//会调用子c覆盖后的方法,哪批怕写在游d中也会执行子c覆盖后的方?BR>        System.out.println("base end");</STRONG></P> <P><STRONG>    }<BR>    static int getNumber(int base)<BR>    {<BR>        System.out.println("base.getNumber int"+base);<BR>        return base;<BR>    }<BR>    public  void draw()<BR>    {<BR>        System.out.println("base.draw");<BR>    }<BR>}</STRONG></P> <P><STRONG>public class JavaBase extends base{<BR>    public int age=getNumber(1001);<BR>    private int _radius=getNumber(10);<BR>    static int sage=getNumber(250);<BR>    static<BR>    {<BR>        System.out.println("subclass static block");<BR>    }<BR>    {<BR>        System.out.println("subclass nonstatic block");<BR>    }<BR>    JavaBase(int radius)<BR>    {<BR>        _radius=radius;<BR>        System.out.println(age);<BR>        System.out.println("initializeOrder initialized");<BR>    }<BR>    public void draw()<BR>    {<BR>        System.out.println("initializeOrder.draw "+_radius);<BR>    }<BR>    /** *//**<BR>     * @param args<BR>     */<BR>    public static void main(String[] args) {<BR>        // TODO Auto-generated method stub<BR>        System.out.println("-------------cd始化开?------------");<BR>        new JavaBase(1000);<BR>        System.out.println("-------------cd始化l束-------------");<BR>    }<BR>}<BR><BR>执行l果:<BR><BR>base static block</STRONG></P> <P><STRONG>base.getNumber int50</STRONG></P> <P><STRONG>base.getNumber int250</STRONG></P> <P><STRONG>subclass static block</STRONG></P> <P><STRONG>-------------cd始化开?------------</STRONG></P> <P><STRONG>base.getNumber int100</STRONG></P> <P><STRONG>base nonstatic block</STRONG></P> <P><STRONG>initializeOrder.draw 0</STRONG></P> <P><STRONG>100</STRONG></P> <P><STRONG>base start</STRONG></P> <P><STRONG>base end</STRONG></P> <P><STRONG>base.getNumber int1001</STRONG></P> <P><STRONG>base.getNumber int10</STRONG></P> <P><STRONG>subclass nonstatic block</STRONG></P> <P><STRONG>1001</STRONG></P> <P><STRONG>initializeOrder initialized</STRONG></P> <P><STRONG>-------------cd始化l束-------------<BR>更正:static</STRONG>静态成员变量和静态初始化是在new对象之前q行?<BR><BR>后待d更正***************************************************************<BR><BR>Static详解:<BR><BR> <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0> <TBODY> <TR> <TD vAlign=top width=413> 一、static <P>  请先看下面这D늨序:</P> <P>  public class Hello{<BR>    public static void main(String[] args){ //(1)<BR>      System.out.println("Hello,world!");   //(2)<BR>    }<BR>  }</P> <P>  看过q段E序Q对于大多数学过Java 的从来说Q都不陌生。即使没有学qJavaQ而学q其它的高语言Q例如CQ那你也应该能看懂这D代码的意思。它只是单的输出“Hello,world”,一点别的用处都没有Q然而,它却展示了static关键字的主要用法?/P><BR> <P></P></TD></TR> <TR> <TD colSpan=2 height=20> <P><BR></P></TD></TR></TBODY></TABLE></P> <P>  ?处,我们定义了一个静态的Ҏ名ؓmainQ这意味着告诉Java~译器,我这个方法不需要创Z个此cȝ对象卛_使用。你q记得你是怎么q行q个E序吗?一般,我们都是在命令行下,打入如下的命令:</P> <P>javac Hello.java<BR>java Hello<BR>Hello,world!</P> <P>  q就是你q行的过E,W一行用来编译Hello.javaq个文gQ执行完后,如果你查看当前,会发现多了一个Hello.class文gQ那是W一行生的Java二进制字节码。第二行是执行一个JavaE序的最普遍做法。执行结果如你所料。在2中,你可能会惻IZ么要q样才能输出。好Q我们来分解一下这条语句。(如果没有安装Java文Q请到Sun的官方网站浏览J2SE APIQ首先,System是位于java.lang包中的一个核心类Q如果你查看它的定义Q你会发现有q样一行:public static final PrintStream out;接着再进一步,点击PrintStreamq个链接,在METHOD面Q你会看到大量定义的ҎQ查找printlnQ会有这样一行:</P> <P>public void println(String x)?/P> <P>  好了Q现在你应该明白Z么我们要那样调用了,out是System的一个静态变量,所以可以直接用,而out所属的cL一个printlnҎ?/P> <P><STRONG>静态方?/STRONG></P> <P>  通常Q在一个类中定义一个方法ؓstaticQ那是_用类名而无需本类的对象即可调用此Ҏ。如下所C:</P> <P>class Simple{<BR>   static void go(){<BR>     System.out.println("Go...");<BR>   }<BR>}<BR>public class Cal{<BR>  public static void main(String[] args){<BR>    Simple.go();<BR>  }<BR>}</P> <P>  调用一个静态方法就是“类?Ҏ名?静态方法的使用很简单如上所C。一般来_静态方法常ؓ应用E序中的其它cL供一些实用工h用,在Java的类库中大量的静态方法正是出于此目的而定义的?/P> <P><STRONG>静态变?/STRONG></P> <P>  静态变量与静态方法类伹{所有此cd例共享此静态变量,也就是说在类装蝲Ӟ只分配一块存储空_所有此cȝ对象都可以操控此块存储空_当然对于final则另当别Z。看下面q段代码Q?/P> <P>class Value{<BR>  static int c=0;<BR>  static void inc(){<BR>    c++;<BR>  }<BR>}<BR>class Count{<BR>  public static void prt(String s){<BR>    System.out.println(s);<BR>  }<BR>  public static void main(String[] args){<BR>    Value v1,v2;<BR>    v1=new Value();<BR>    v2=new Value();<BR>    prt("v1.c="+v1.c+"  v2.c="+v2.c);<BR>    v1.inc();<BR>    prt("v1.c="+v1.c+"  v2.c="+v2.c);  <BR>  }<BR>}</P> <P>  l果如下Q?/P> <P>v1.c=0  v2.c=0<BR>v1.c=1  v2.c=1</P> <P>由此可以证明它们׃n一块存储区。static变量有点cM于C中的全局变量的概c值得探讨的是静态变量的初始化问题。我们修改上面的E序Q?/P> <P>class Value{<BR>  static int c=0;<BR>  Value(){<BR>    c=15;<BR>  }<BR>  Value(int i){<BR>    c=i;<BR>  }<BR>  static void inc(){<BR>    c++;<BR>  }<BR>}<BR>class Count{<BR>  public static void prt(String s){<BR>    System.out.println(s);<BR>  }<BR>    Value v=new Value(10);<BR>    static Value v1,v2;<BR>    static{<BR>      prt("v1.c="+v1.c+"  v2.c="+v2.c);<BR>      v1=new Value(27);<BR>      prt("v1.c="+v1.c+"  v2.c="+v2.c);<BR>      v2=new Value(15);<BR>      prt("v1.c="+v1.c+"  v2.c="+v2.c);<BR>    }</P> <P>  public static void main(String[] args){<BR>    Count ct=new Count();<BR>    prt("ct.c="+ct.v.c);<BR>    prt("v1.c="+v1.c+"  v2.c="+v2.c);<BR>    v1.inc();<BR>    prt("v1.c="+v1.c+"  v2.c="+v2.c);<BR>    prt("ct.c="+ct.v.c);<BR>  }<BR>}</P> <P>q行l果如下Q?/P> <P>v1.c=0  v2.c=0<BR>v1.c=27  v2.c=27<BR>v1.c=15  v2.c=15<BR>ct.c=10<BR>v1.c=10  v2.c=10<BR>v1.c=11  v2.c=11<BR>ct.c=11</P> <P>  q个E序展示了静态初始化的各U特性。如果你初次接触JavaQ结果可能o你吃惊。可能会对static后加大括h到困惑。首先要告诉你的是,static定义的变量会优先于Q何其它非static变量Q不论其出现的顺序如何。正如在E序中所表现的,虽然v出现在v1和v2的前面,但是l果却是v1和v2的初始化在v的前面。在static{后面跟着一D代码,q是用来q行昑ּ的静态变量初始化Q这D代码只会初始化一ơ,且在c被W一ơ装载时。如果你能读懂ƈ理解q段代码Q会帮助你对static关键字的认识。在涉及到承的时候,会先初始化父cȝstatic变量Q然后是子类的,依次cL?/P> <P>  通常一个普通类不允许声明ؓ静态的Q只有一个内部类才可以。这时这个声明ؓ静态的内部cd以直接作Z个普通类来用,而不需实例一个外部类。如下代码所C:</P> <P>public class StaticCls{<BR>  public static void main(String[] args){<BR>    OuterCls.InnerCls oi=new OuterCls.InnerCls();<BR>  }<BR>}<BR>class OuterCls{<BR>  public static class InnerCls{<BR>    InnerCls(){<BR>      System.out.println("InnerCls");<BR>    }<BR>   }<BR>}</P> <P>  输出l果会如你所料:</P> <P>InnerCls</P><img src ="http://www.aygfsteel.com/fjq639/aggbug/24904.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/fjq639/" target="_blank">黑石</a> 2005-12-21 09:12 <a href="http://www.aygfsteel.com/fjq639/archive/2005/12/21/24904.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Junit概述http://www.aygfsteel.com/fjq639/archive/2005/12/20/24833.html黑石黑石Tue, 20 Dec 2005 10:02:00 GMThttp://www.aygfsteel.com/fjq639/archive/2005/12/20/24833.htmlhttp://www.aygfsteel.com/fjq639/comments/24833.htmlhttp://www.aygfsteel.com/fjq639/archive/2005/12/20/24833.html#Feedback1http://www.aygfsteel.com/fjq639/comments/commentRss/24833.htmlhttp://www.aygfsteel.com/fjq639/services/trackbacks/24833.html  Junit试是程序员试Q即所谓白盒测试,因ؓE序员知道被试的Y件如何(HowQ完成功能和完成什么样QWhatQ的功能?BR>  Junit本质上是一套框Ӟ卛_发者制定了一套条条框框,遵@q此条条框框要求~写试代码Q如l承某个c,实现某个接口Q就可以用Junitq行自动试了?BR>  ׃Junit相对独立于所~写的代码,可以试代码的编写可以先于实C码的~写QXP 中推崇的 test first design的实现有了现成的手段Q用Junit写测试代码,写实C码,q行试Q测试失败,修改实现代码Q再q行试Q直到测试成功。以后对代码的修改和优化Q运行测试成功,则修Ҏ功?BR>  Java 下的 team 开发,采用 cvs(版本控制) + ant(目理) + junit(集成试) 的模式时Q通过对ant的配|,可以很简单地实现试自动化?BR>
  对不同性质的被对象,如ClassQJspQServletQEjb{,Junit有不同的使用技巧,以后慢慢地分别讲叙。以下以Class试Z讲解Q除非特D说明?BR>
2、下载安?BR>

去Junit主页下蝲最新版?.8.1E序包junit-3.8.1.zip

用winzip或unzipjunit-3.8.1.zip解压~到某一目录名ؓ$JUNITHOME

junit.jar?JUNITHOME/junit加入到CLASSPATH中,加入后者只因ؓ试例程在那个目录下?BR>
注意不要junit.jar攑֜jdk的extension目录?BR>
q行命o,l果如下图?BR>java junit.swingui.TestRunner junit.samples.AllTests



3、Junit架构
  下面以Moneyq个cMؓ例进行说明?BR>
public class Money {
    private int fAmount;//余额
    private String fCurrency;//货币cd

    public Money(int amount, String currency) {
        fAmount= amount;
        fCurrency= currency;
    }

    public int amount() {
        return fAmount;
    }

    public String currency() {
        return fCurrency;
    }
   
    public Money add(Money m) {//加钱
        return new Money(amount()+m.amount(), currency());
    }
   
    public boolean equals(Object anObject) {//判断钱数是否相等
        if (anObject instanceof Money) {
            Money aMoney= (Money)anObject;
            return aMoney.currency().equals(currency())
                && amount() == aMoney.amount();
        }
        return false;
    }   
}


  Junit本n是围l着两个设计模式来设计的Q命令模式和集成模式.

命o模式
  利用TestCase定义一个子c,在这个子cM生成一个被试的对象,~写代码某个方法被调用后对象的状态与预期的状态是否一_q而断aE序代码有没有bug?BR>  当这个子c要试不只一个方法的实现代码Ӟ可以先徏立测试基Q让q些试在同一个基上运行,一斚w可以减少每个试的初始化Q而且可以试q些不同Ҏ之间的联pR?BR>  例如Q我们要试Money的AddҎQ可以如?
public class MoneyTest extends TestCase { //TestCase的子c?BR>    public void testAdd() { //把测试代码放在testAdd?BR>        Money m12CHF= new Money(12, "CHF");  //本行和下一行进行一些初始化
        Money m14CHF= new Money(14, "CHF");        
        Money expected= new Money(26, "CHF");//预期的结?BR>        Money result= m12CHF.add(m14CHF);    //q行被测试的Ҏ
        Assert.assertTrue(expected.equals(result));     //判断q行l果是否与预期的相同
    }
}

  如果试一下equalsҎQ用cM的代码,如下Q?BR>public class MoneyTest extends TestCase { //TestCase的子c?BR>    public void testEquals() { //把测试代码放在testEquals?BR>        Money m12CHF= new Money(12, "CHF"); //本行和下一行进行一些初始化
        Money m14CHF= new Money(14, "CHF");

        Assert.assertTrue(!m12CHF.equals(null));//q行不同情况的测?BR>        Assert.assertEquals(m12CHF, m12CHF);
        Assert.assertEquals(m12CHF, new Money(12, "CHF")); // (1)
        Assert.assertTrue(!m12CHF.equals(m14CHF));
    }
}


  当要同时q行试Add和equalsҎӞ可以它们的各自的初始化工作Q合q到一赯行,形成试基础,用setUp初始化,用tearDown清除。如下:
public class MoneyTest extends TestCase {//TestCase的子c?BR>    private Money f12CHF;//提取公用的对?BR>    private Money f14CHF;   

    protected void setUp() {//初始化公用对?BR>        f12CHF= new Money(12, "CHF");
        f14CHF= new Money(14, "CHF");
    }
    public void testEquals() {//试equalsҎ的正?BR>        Assert.assertTrue(!f12CHF.equals(null));
        Assert.assertEquals(f12CHF, f12CHF);
        Assert.assertEquals(f12CHF, new Money(12, "CHF"));
        Assert.assertTrue(!f12CHF.equals(f14CHF));
    }
   
    public void testSimpleAdd() {//试addҎ的正?BR>        Money expected= new Money(26, "CHF");
        Money result= f12CHF.add(f14CHF);
        Assert.assertTrue(expected.equals(result));
    }
}


  以上三个中的Q一个TestCase子类代码保存到名为MoneyTest.java的文仉Qƈ在文仉行增?BR>import junit.framework.*;
Q都是可以运行的。关于Junitq行的问题很有意思,下面单独说明?BR>  上面释概念“测试基(fixture)”,引入了两个对两个Ҏ的测试。命令模式与集成模式的本质区别是Q前者一ơ只q行一个测试?BR>
集成模式
  利用TestSuite可以一个TestCase子类中所有test***()Ҏ包含q来一赯行,q可TestSuite子类也包含进来,从而行成了一U等U关pR可以把TestSuite视ؓ一个容器,可以盛放TestCase中的test***()ҎQ它自己也可以嵌套。这U体pL构,非常cM于现实中E序一步步开发一步步集成的现c?BR>  对上面的例子Q有代码如下Q?BR>public class MoneyTest extends TestCase {//TestCase的子c?BR>    ....
    public static Test suite() {//静态Test
        TestSuite suite= new TestSuite();//生成一个TestSuite
        suite.addTest(new MoneyTest("testEquals")); //加入试Ҏ
        suite.addTest(new MoneyTest("testSimpleAdd"));
        return suite;
    }
}

  从Junit2.0开始,有列LҎ:
public class MoneyTest extends TestCase {//TestCase的子c?BR>    ....
    public static Test suite() {静态Test
        return new TestSuite(MoneyTest.class); //以类为参?BR>    }
}

  TestSuite见嵌套的例子Q在后面应用案例中有?BR>  

4、测试代码的q行
  先说最常用的集成模式?BR>  试代码写好以后Q可以相应的cM写mainҎQ用java命o直接q行Q也可以不写mainҎQ用Junit提供的运行器q行。Junit提供了textui,awtui和swingui三种q行器?BR>  以前面第2步中的AllTestsq行ZQ可有四U:

java junit.textui.TestRunner junit.samples.AllTests
java junit.awtui.TestRunner junit.samples.AllTests
java junit.swingui.TestRunner junit.samples.AllTests
java junit.samples.AllTests

  mainҎ中一般也都是单地用Runner调用suite()Q当没有mainӞTestRunner自己以运行的cMؓ参数生成了一个TestSuite.
  
  对于命o模式的运行,有两U方法?BR>
静态方?BR>
TestCase test= new MoneyTest("simple add") {
public void runTest() {
testSimpleAdd();
}
};


动态方?BR>
TestCase test= new MoneyTest("testSimpleAdd");

  我试了一下,好象有问题,哪位朋友成功了,hҎ一下。确实可以?BR>
import junit.framework.*;

public class MoneyTest extends TestCase {//TestCase的子c?BR>    private Money f12CHF;//提取公用的对?BR>    private Money f14CHF;   
    public MoneyTest(String name){
        super(name);
    }
    protected void setUp() {//初始化公用对?BR>        f12CHF= new Money(12, "CHF");
        f14CHF= new Money(14, "CHF");
    }
    public void testEquals() {//试equalsҎ的正?BR>        Assert.assertTrue(!f12CHF.equals(null));
        Assert.assertEquals(f12CHF, f12CHF);
        Assert.assertEquals(f12CHF, new Money(12, "CHF"));
        Assert.assertTrue(!f12CHF.equals(f14CHF));
    }
   
    public void testAdd() {//试addҎ的正?BR>        Money expected= new Money(26, "CHF");
        Money result= f12CHF.add(f14CHF);
        Assert.assertTrue(expected.equals(result));
    }
//    public static void main(String[] args) {
//        TestCase test=new MoneyTest("simple add") {
//                public void runTest() {
//                    testAdd();
//                }
//            };
//        junit.textui.TestRunner.run(test);
//    }
    public static void main(String[] args) {
        TestCase test=new MoneyTest("testAdd");
        junit.textui.TestRunner.run(test);
    }
}


再给一个静态方法用集成试的例子:
public static Test suite() {
    TestSuite suite= new TestSuite();
    suite.addTest(
        new testCar("getWheels") {
            protected void runTest() { testGetWheels(); }
        }
    );

    suite.addTest(
        new testCar("getSeats") {
            protected void runTest() { testGetSeats(); }
        }
    );
    return suite;
}


5、应用案?BR>

Junit Primer例程Q运行如下:
java com.hedong.JunitLearning.Primer.ShoppingCartTest


Ant+Junit+Mailto实现自动~译、调试ƈ发送结果的build.xml

JUnit实施,写得很棒Q理解也深刻。例E运行如下:
java com.hedong.JunitLearning.car.testCarNoJunit
java junit.swingui.TestRunner com.hedong.JunitLearning.car.testCar


Junit与log4jl合Q阿菜的例程q行Q?BR>cd acai
ant junit











6、一些问?BR>  有h在实践基上ȝZ些非常有价值的使用技巧,我没有经q一一“测试”,暂列在此?BR>
不要用TestCase的构造函数初始化FixtureQ而要用setUp()和tearDown()Ҏ?BR>
不要依赖或假定测试运行的序Q因为JUnit利用Vector保存试Ҏ。所以不同的q_会按不同的顺序从Vector中取出测试方法。不?.8中是不是q是如此Q不q它提供的例子有一个是指定用VectorSuite的,如果不指定呢Q?BR>
避免~写有副作用的TestCase。例如:如果随后的测试依赖于某些特定的交易数据,׃要提交交易数据。简单的回滚可以了?BR>
当承一个测试类Ӟ记得调用父类的setUp()和tearDown()Ҏ?BR>
测试代码和工作代码攑֜一P一边同步编译和更新。(使用Ant中有支持junit的task.Q?BR>
试cd试Ҏ应该有一致的命名Ҏ。如在工作类名前加上test从而Ş成测试类名?BR>
保试与时间无养I不要依赖使用q期的数据进行测试。导致在随后的维护过E中很难重现试?BR>
如果你编写的软g面向国际市场Q编写测试时要考虑国际化的因素。不要仅用母语的Localeq行试?BR>
可能地利用JUnit提供地assert/failҎ以及异常处理的方法,可以使代码更为简z?BR>
试要尽可能地小Q执行速度快?BR>
把测试程序徏立在与被对象相同的包中

在你的原始代码目录中避免试码出玎ͼ可在一个源码镜像目录中放测试码

在自q应用E序包中包含一个TestSuite试c?BR>




7、相兌源下?BR>以下jar包,我只是做了打包、编译和调试的工作,供下载学习之用,相关的权利属于原作者?BR>
可运行例E?jar

Build.xml

阿菜的例E?BR>
Junit API 汉译(pdf)


8、未完成的Q?BR>

httpunit

cactus

Junit用链接池试


主要参考文献:



JUnit入門
[url]http://www.dotspace.twmail.org/Test/JUnit_Primer.htm[/url]

怎样使用Junit Frameworkq行单元试的编?BR>[url]http://www.chinaunix.net/bbsjh/14/546.html[/url]

Ant+Junit+Log4J+CVSq行XP模式开发的建立
[url]http://ejb.cn/modules/tutorials/printpage.php?tid=4[/url]

用HttpUnit试Web应用E序
[url]http://www.zdnet.com.cn/developer/code/story/0[/url],2000081534,39033726,00.htm

有没有用qCactus的,Web层的试是Cactusq是JUnitQ?BR>[url]http://www.jdon.com/jive/thread.jsp?forum=16&thread=9156[/url]

Ant+junit的测试自动化 biggieQ原作)
[url]http://www.csdn.net/Develop/article/19%5C19748.shtm[/url]

JUnit实施
[url]http://www.neweasier.com/article/2002-08-07/1028723459.html[/url]

JUnitTest Infected: Programmers Love Writing Tests
[url]http://junit.sourceforge.net/doc/testinfected/testing.htm[/url]

JUnit Cookbook
[url]http://junit.sourceforge.net/doc/cookbook/cookbook.htm[/url]

JUnit Primer
[url]http://www.itu.dk/~lthorup/JUnitPrimer.html[/url]

IBM DevelopWorks
[url]http://www-106.ibm.com/search/searchResults.jsp?query=junit&searchScope=dW&[/url]
searchType=1&searchSite=dWChina&pageLang=zh&langEncoding=gb2312&Search.x=0&
Search.y=0&Search=Search

黑石 2005-12-20 18:02 发表评论
]]>
վ֩ģ壺 | | | | | | | | | | ԫ| ͷ| | ׯ| ֯| | | | | | Դ| ̨| | ̨| | | | | ɾ| | ֹ| ˳| | | ؼ| | | | | | IJ|