??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
CZQ?/p>
InputStream in = lnew BufferedInputStream(new FileInputStream(name));
Properties p = new Properties();
p.load(in);
2。用java.util.ResourceBundlecȝgetBundle()Ҏ(gu)
CZQ?/p>
ResourceBundle rb = ResourceBundle.getBundle(name, Locale.getDefault());
3。用java.util.PropertyResourceBundlecȝ构造函?/p>
CZQ?/p>
InputStream in = new BufferedInputStream(new FileInputStream(name));
ResourceBundle rb = new PropertyResourceBundle(in);
4。用class变量的getResourceAsStream()Ҏ(gu)
CZQ?/p>
InputStream in = JProperties.class.getResourceAsStream(name);
Properties p = new Properties();
p.load(in);
5。用class.getClassLoader()所得到的java.lang.ClassLoader的getResourceAsStream()Ҏ(gu)
CZQ?/p>
InputStream in = JProperties.class.getClassLoader().getResourceAsStream(name);
Properties p = new Properties();
p.load(in);
6。用java.lang.ClassLoadercȝgetSystemResourceAsStream()静态方?/p>
CZQ?/p>
InputStream in = ClassLoader.getSystemResourceAsStream(name);
Properties p = new Properties();
p.load(in);
补充
Servlet中可以用javax.servlet.ServletContext的getResourceAsStream()Ҏ(gu)
CZQ?/p>
InputStream in = context.getResourceAsStream(path);
Properties p = new Properties();
p.load(in);
工厂模式Q客L(fng)和工厂类分开。消费者Q何时候需要某U品,只需向工厂请求即可。消费者无M改就可以接纳C品。缺Ҏ(gu)当品修Ҏ(gu)Q工厂类也要做相应的修改。如Q如何创建及(qing)如何向客L(fng)提供?
2、BUILDER—MM最爱听的就?#8220;我爱?#8221;q句话了Q见C同地方的MM,要能够用她们的方a跟她说这句话哦,我有一个多U语a译机,上面每种语言都有一个按键,见到MM我只要按对应的键Q它?yu)p够用相应的语a说出“我爱?#8221;q句话了Q国外的MM也可以轻松搞掂,q就是我?#8220;我爱?#8221;builder。(q一定比军在伊拉克用的译机好卖)
建造模式:(x)品的内部表象和品的生成q程分割开来,从而一个徏造过E生成具有不同的内部表象的品对象。徏造模式得品内部表象可以独立的变化Q客户不必知道品内部组成的l节。徏造模式可以强制实行一U分步骤q行的徏造过E?
3、FACTORY METHOD—请MM去麦当劳吃汉堡,不同的MM有不同的口味Q要每个都记住是一件烦人的事情Q我一般采用Factory Method模式Q带着MM到服务员那儿Q说“要一个汉?#8221;Q具体要什么样的汉堡呢Q让MM直接跟服务员说就行了?
工厂Ҏ(gu)模式Q核心工厂类不再负责所有品的创徏Q而是具体创建的工作交给子类dQ成Z个抽象工厂角Ԍ仅负责给出具体工厂类必须实现的接口,而不接触哪一个品类应当被实例化q种l节?
4、PROTOTYPE—跟MM用QQ聊天Q一定要说些深情的话语了Q我搜集了好多肉ȝ情话Q需要时只要copy出来攑ֈQQ里面p了,q就是我的情话prototype了。(100块钱一份,你要不要Q?
原始模型模式Q通过l出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的Ҏ(gu)创徏出更多同cd的对象。原始模型模式允许动态的增加或减品类Q品类不需要非得有M事先定的等U结构,原始模型模式适用于Q何的{l构。缺Ҏ(gu)每一个类都必配备一个克隆方法?
5、SINGLETON—俺?个漂亮的老婆Q她们的老公都是我,我就是我们家里的老公SigletonQ她们只要说?#8220;老公”Q都是指的同一个hQ那是?刚才做了个梦啦,哪有q么好的?
单例模式Q单例模式确保某一个类只有一个实例,而且自行实例化ƈ向整个系l提供这个实例单例模式。单例模式只应在有真正的“单一实例”的需求时才可使用?
l构型模?
6、ADAPTER—在朋友聚会(x)上碰C一个美女SarahQ从香港来的Q可我不?x)说_语Q她不会(x)说普通话Q只好求助于我的朋友kent了,他作为我和Sarah之间的AdapterQ让我和Sarah可以怺交谈?也不知道他会(x)不会(x)耍我)
适配器(变压器)模式Q把一个类的接口变换成客户端所期待的另一U接口,从而原本因接口原因不匚w而无法一起工作的两个c能够一起工作。适配cd以根据参数返q一个合适的实例l客L(fng)?
7、BRIDGE—早上碰到MMQ要说早上好Q晚上碰到MMQ要说晚上好Q碰到MMI了件新衣服Q要说你的衣服好漂亮哦,到MM新做的发型,要说你的头发好漂亮哦。不要问?#8220;早上到MM新做了个发型怎么?#8221;q种问题Q自qBRIDGEl合一下不p?
桥梁模式Q将抽象化与实现化脱耦,使得二者可以独立的变化Q也是说将他们之间的强兌变成弱关联,也就是指在一个Y件系l的抽象化和实现化之间用组?聚合关系而不是承关p,从而两者可以独立的变化?
8、COMPOSITE—Mary今天q生日?#8220;我过生日Q你要送我一件礼物?#8221;“嗯,好吧Q去商店Q你自己挑?#8221;“qgT恤挺漂亮Q买Q这条裙子好看,乎ͼq个包也不错Q买?#8221;“喂,C三g了呀Q我只答应送一件礼物的哦?#8221;“什么呀QT恤加裙子加包包,正好配成一套呀Q小姐,ȝ你包h?#8221;“……”QMM都会(x)用Composite模式了,你会(x)了没有?
合成模式Q合成模式将对象l织到树(wi)l构中,可以用来描述整体与部分的关系。合成模式就是一个处理对象的?wi)结构的模式。合成模式把部分与整体的关系用树(wi)l构表示出来。合成模式得客L(fng)把一个个单独的成分对象和׃们复合而成的合成对象同{看待?
9、DECORATOR—Maryq完轮到Sarlyq生日,q是不要叫她自己挑了Q不然这个月伙食费肯定玩完,拿出我去q在华山上照的照片Q在背面写上“最好的的礼物,是׃的Fita”Q再到街上礼品店C个像框(卖礼品的MM也很漂亮哦)Q再N壁搞术设计的Mike设计了一个漂亮的盒子装v?#8230;…Q我们都是DecoratorQ最l都在修饰我q个人呀Q怎么P看懂了吗Q?
装饰模式Q装饰模式以对客L(fng)透明的方式扩展对象的功能Q是l承关系的一个替代方案,提供比承更多的灉|性。动态给一个对象增加功能,q些功能可以再动态的撤消。增加由一些基本功能的排列l合而生的非常大量的功能?
10、FACADE—我有一个专业的Nikon相机Q我喜Ƣ自己手动调光圈、快门,q样照出来的照片才专业,但MM可不懂这些,教了半天也不?x)。幸好相机有Facade设计模式Q把相机调整到自动档Q只要对准目标按快门p了,一切由相机自动调整Q这样MM也可以用q个相机l我拍张照片了?
门面模式Q外部与一个子pȝ的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口,使得子系l更易于使用。每一个子pȝ只有一个门面类Q而且此门面类只有一个实例,也就是说它是一个单例模式。但整个pȝ可以有多个门面类?
11、FLYWEIGHT—每天跟MM发短信,手指都篏MQ最q买了个新手机,可以把一些常用的句子存在手机里,要用的时候,直接拿出来,在前面加上MM的名字就可以发送了Q再不用一个字一个字敲了。共享的句子是FlyweightQMM的名字就是提取出来的外部特征Q根据上下文情况使用?
享元模式QFLYWEIGHT在拳?yn)L赛中指最轻量U。n元模式以׃n的方式高效的支持大量的细_度对象。n元模式能做到׃n的关键是区分内蕴状态和外蕴状态。内蕴状态存储在享元内部Q不?x)随环境的改变而有所不同。外蕴状态是随环境的改变而改变的。外蕴状态不能媄响内蕴状态,它们是相互独立的。将可以׃n的状态和不可以共享的状态从常规cM区分开来,不可以׃n的状态从c里剔除出去。客L(fng)不可以直接创׃n的对象,而应当用一个工厂对象负责创׃n的对象。n元模式大q度的降低内存中对象的数量?
12、PROXY—跟MM在网上聊天,一开头L“hi,你好”,“你从哪儿来呀Q?#8221;“你多大了Q?#8221;“w高多少呀Q?#8221;q些话,真烦人,写个E序做ؓ(f)我的Proxy吧,凡是接收到这些话都设|好了自动的回答Q接收到其他的话时再通知我回{,怎么P酷吧?
代理模式Q代理模式给某一个对象提供一个代理对象,q由代理对象控制Ҏ(gu)对象的引用。代理就是一个h或一个机构代表另一个h或者一个机构采取行动。某些情况下Q客户不x者不能够直接引用一个对象,代理对象可以在客户和目标对象直接起到中介的作用。客L(fng)分L不出代理主题对象与真实主题对象。代理模式可以ƈ不知道真正的被代理对象,而仅仅持有一个被代理对象的接口,q时候代理对象不能够创徏被代理对象,被代理对象必Lpȝ的其他角色代为创建ƈ传入?
行ؓ(f)模式
13、CHAIN OF RESPONSIBLEITY—晚上去上英语课Qؓ(f)了好开溜坐C最后一排,哇,前面坐了好几个漂亮的MM哎,扑ּU条Q写?#8220;Hi,可以做我的女朋友吗?如果不愿意请向前?#8221;Q纸条就一个接一个的传上MQ糟p,传到W一排的MM把纸条传l老师了,听说是个老处奛_Q快?
责Q链模式:(x)在责任链模式中,很多对象由每一个对象对其下家的引用而接
h形成一条链。请求在q个链上传递,直到链上的某一个对象决定处理此h。客户ƈ不知道链上的哪一个对象最l处理这个请求,pȝ可以在不影响客户端的情况下动态的重新l织铑֒分配责Q。处理者有两个选择Q承担责L者把责Q推给下家。一个请求可以最l不被Q何接收端对象所接受?
14、COMMAND—俺有一个MM安得特别严,没法见面Q只好借助于她弟弟在我们俩之间传送信息,她对我有什么指C,写一张纸条让她弟弟带l我。这不,她弟弟又传送过来一个COMMANDQؓ(f)了感谢他Q我请他吃了杂酱面Q哪知道他说Q?#8220;我同时给我姐姐三个男朋友送COMMANDQ就C最气Q才h吃面?#8221;Q?
命o(h)模式Q命令模式把一个请求或者操作封装到一个对象中。命令模式把发出命o(h)的责d执行命o(h)的责d割开Q委z不同的对象。命令模式允许请求的一方和发送的一方独立开来,使得h的一方不必知道接收请求的一方的接口Q更不必知道h是怎么被接Ӟ以及(qing)操作是否执行Q何时被执行以及(qing)是怎么被执行的。系l支持命令的撤消?
15、INTERPRETER—俺有一个《MM真经》,上面有各UMM的攻略,比如说去吃西的步骤、去看电(sh)qҎ(gu){等Q跟MMU会(x)Ӟ只要做一个InterpreterQ照着上面的脚本执行就可以了?
解释器模式:(x)l定一个语a后,解释器模式可以定义出其文法的一U表C,q同时提供一个解释器。客L(fng)可以使用q个解释器来解释q个语言中的句子。解释器模式描q怎样在有了一个简单的文法后,使用模式设计解释q些语句。在解释器模式里面提到的语言是指M解释器对象能够解释的Ml合。在解释器模式中需要定义一个代表文法的命o(h)cȝ{l构Q也是一pd的组合规则。每一个命令对象都有一个解释方法,代表对命令对象的解释。命令对象的{l构中的对象的Q何排列组合都是一个语a?
16、ITERATOR—我׃了MaryQ不一切的向她求婚?
MaryQ?#8220;惌我跟你结婚,得答应我的条?#8221;
我:(x)“什么条件我都答应,你说?#8221;
MaryQ?#8220;我看上了那个一克拉的钻?#8221;
我:(x)“我买Q我乎ͼq有吗?”
MaryQ?#8220;我看上了湖边的那栋别?#8221;
我:(x)“我买Q我乎ͼq有吗?”
MaryQ?#8220;我看上那辆法拉利跑R”
我脑袋嗡的一壎ͼ坐在椅子上,一咬牙Q?#8220;我买Q我乎ͼq有吗?”
……
q代子模式:(x)q代子模式可以顺序访问一个聚集中的元素而不必暴露聚集的内部表象。多个对象聚在一起Ş成的MUC集,聚集对象是能够包容一l对象的容器对象。P代子模式P代逻辑装C个独立的子对象中Q从而与聚集本n隔开。P代子模式化了聚集的界面。每一个聚集对象都可以有一个或一个以上的q代子对象,每一个P代子的P代状态可以是彼此独立的。P代算法可以独立于聚集角色变化?
17、MEDIATOR—四个MM打麻,怺之间谁应该给谁多钱不清楚了,q怺当时我在旁边Q按照各自的{码数算钱,赚了q从我q里拿,赔了q也付l我Q一切就O(jin)K啦,俺得C四个MM的电(sh)话?
调停者模式:(x)调停者模式包装了一pd对象怺作用的方式,使得q些对象不必怺明显作用。从而他们可以松散偶合。当某些对象之间的作用发生改变时Q不?x)立卛_响其他的一些对象之间的作用。保证这些作用可以彼此独立的变化。调停者模式将多对多的怺作用转化Z对多的相互作用。调停者模式将对象的行为和协作抽象化,把对象在尺度的行ؓ(f)上与其他对象的相互作用分开处理?
18、MEMENTO—同时跟几个MM聊天Ӟ一定要记清楚刚才跟MM说了些什么话Q不然MM发现了会(x)不高兴的哦,q怺我有个备忘录Q刚才与哪个MM说了什么话我都拯一份放到备忘录里面保存Q这样可以随时察看以前的记录啦?
备忘录模式:(x)备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏装的条件下Q将一个对象的状态捉住,q外部化Q存储v来,从而可以在来合适的时候把q个对象q原到存储v来的状态?
19、OBSERVER—想知道׃公司最新MM情报吗?加入公司的MM情报邮gl就行了Qtom负责搜集情报Q他发现的新情报不用一个一个通知我们Q直接发布给邮gl,我们作ؓ(f)订阅者(观察者)可以及(qing)时收到情报啦
观察者模式:(x)观察者模式定义了一U一队多的依赖关p,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化Ӟ?x)通知所有观察者对象,使他们能够自动更新自己?
20、STATE—跟MM交往Ӟ一定要注意她的状态哦Q在不同的状态时她的行ؓ(f)?x)有不同Q比如你U她今天晚上ȝ?sh)媄Q对你没兴趣的MM׃(x)?#8220;有事情啦”Q对你不讨厌但还没喜Ƣ上的MM׃(x)?#8220;好啊Q不q可以带上我同事么?”Q已l喜Ƣ上你的MM׃(x)?#8220;几点钟?看完?sh)媄再去泡吧怎么P”Q当然你看电(sh)pE中表现良好的话Q也可以把MM的状态从不讨厌不喜欢变成喜欢哦?
状态模式:(x)状态模式允怸个对象在其内部状态改变的时候改变行为。这个对象看上去象是改变了它的类一栗状态模式把所研究的对象的行ؓ(f)包装在不同的状态对象里Q每一个状态对象都属于一个抽象状态类的一个子cR状态模式的意图是让一个对象在其内部状态改变的时候,其行Z随之改变。状态模式需要对每一个系l可能取得的状态创立一个状态类的子cR当pȝ的状态变化时Q系l便改变所选的子类?
21、STRATEGY—跟不同cd的MMU会(x)Q要用不同的{略Q有的请?sh)媄比较好,有的则去吃小吃效果不错,有的LvҎ(gu)漫最合适,单目的都是ؓ(f)了得到MM的芳心,我的qMM锦囊中有好多Strategy哦?
{略模式Q策略模式针对一l算法,每一个算法封装到h共同接口的独立的cMQ从而得它们可以相互替换。策略模式得算法可以在不媄响到客户端的情况下发生变化。策略模式把行ؓ(f)和环境分开。环境类负责l持和查询行为类Q各U算法在具体的策略类中提供。由于算法和环境独立开来,法的增减,修改都不?x)媄响到环境和客L(fng)?
22、TEMPLATE METHOD——看q《如何说服女生上床》这部经典文章吗Q女生从认识C床的不变的步骤分为y遇、打破僵局、展开q求、接吅R前戏、动手、爱抚、进d大步?Template method)Q但每个步骤针对不同的情况,都有不一L(fng)做法Q这p看你随机应变?具体实现)Q?
模板Ҏ(gu)模式Q模板方法模式准备一个抽象类Q将部分逻辑以具体方法以?qing)具体构造子的Ş式实玎ͼ然后声明一些抽象方法来q子类实现剩余的逻辑。不同的子类可以以不同的方式实现q些抽象Ҏ(gu)Q从而对剩余的逻辑有不同的实现。先制定一个顶U逻辑框架Q而将逻辑的细节留l具体的子类d现?
23、VISITOR—情CQ要l每个MM送一束鲜花和一张卡片,可是每个MM送的花都要针对她个h的特点,每张卡片也要Ҏ(gu)个h的特Ҏ(gu)挑,我一个h哪搞得清楚,q是找花店老板和礼品店老板做一下VisitorQ让花店老板Ҏ(gu)MM的特炚w一束花Q让C品店老板也根据每个h特点选一张卡Q这样就L多了Q?
讉K者模式:(x)讉K者模式的目的是封装一些施加于某种数据l构元素之上的操作。一旦这些操作需要修改的话,接受q个操作的数据结构可以保持不变。访问者模式适用于数据结构相Ҏ(gu)定的pȝQ它把数据结构和作用于结构上的操作之间的耦合解脱开Q得操作集合可以相对自q演化。访问者模式得增加新的操作变的很Ҏ(gu)Q就是增加一个新的访问者类。访问者模式将有关的行为集中到一个访问者对象中Q而不是分散到一个个的节点类中。当使用讉K者模式时Q要尽可能多的对象览逻辑攑֜讉K者类中,而不是放到它的子cM。访问者模式可以跨q几个类的等U结构访问属于不同的{l构的成员类?/p>
本文来自CSDN博客Q{载请标明出处Qhttp://blog.csdn.net/surfingsoft_mda/archive/2009/11/18/4830007.aspx
import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;
import org.xml.sax.InputSource;
public class DuXMLDoc {
public List xmlElements(String xmlDoc) {
//创徏一个新的字W串
StringReader read = new StringReader(xmlDoc);
//创徏新的输入源SAX 解析器将使用 InputSource 对象来确定如何读?XML 输入
InputSource source = new InputSource(read);
//创徏一个新的SAXBuilder
SAXBuilder sb = new SAXBuilder();
try {
//通过输入源构造一个Document
Document doc = sb.build(source);
//取的根元?
Element root = doc.getRootElement();
System.out.println(root.getName());//输出根元素的名称Q测试)
//得到根元素所有子元素的集?
List jiedian = root.getChildren();
//获得XML中的命名I间QXML中未定义可不写)
Namespace ns = root.getNamespace();
Element et = null;
for(int i=0;i<jiedian.size();i++){
et = (Element) jiedian.get(i);//循环依次得到子元?
/**//*
* 无命名空间定义时
* et.getChild("users_id").getText();
* et.getChild("users_address",ns).getText()
*/
System.out.println(et.getChild("users_id",ns).getText());
System.out.println(et.getChild("users_address",ns).getText());
}
/**//*
* 如要?lt;row>下的子元素的名称
*/
et = (Element) jiedian.get(0);
List zjiedian = et.getChildren();
for(int j=0;j<zjiedian.size();j++){
Element xet = (Element) zjiedian.get(j);
System.out.println(xet.getName());
}
} catch (JDOMException e) {
// TODO 自动生成 catch ?
e.printStackTrace();
} catch (IOException e) {
// TODO 自动生成 catch ?
e.printStackTrace();
}
return null;
}
public static void main(String[] args){
DuXMLDoc doc = new DuXMLDoc();
String xml = "<?xml version=\"1.0\" encoding=\"gb2312\"?>"+
"<Result xmlns=\"http://www.fiorano.com/fesb/activity/DBQueryOnInput2/Out\">"+
"<row resultcount=\"1\">"+
"<users_id>1001 </users_id>"+
"<users_name>wangwei </users_name>"+
"<users_group>80 </users_group>"+
"<users_address>1001?nbsp; </users_address>"+
"</row>"+
"<row resultcount=\"1\">"+
"<users_id>1002 </users_id>"+
"<users_name>wangwei </users_name>"+
"<users_group>80 </users_group>"+
"<users_address>1002?nbsp; </users_address>"+
"</row>"+
"</Result>";
doc.xmlElements(xml);
}
}
2、设|系l环境变量,右键单击“我的?sh)?#8221;à选择“属?#8221;à选择“高”选项卡,打开如图2所C的pȝ属性面版块Q?/p>
3、在pȝ属性版块里单击“环境变量QNQ?#8221;按钮Q打开?Q?/p>
4、选择“pȝ变量QSQ?#8221;里的“新徏QWQ?#8221;按钮Q打开“~辑pȝ变量”对话框,如图4所C,然后?#8220;变量|VQ?#8221;里加?#8220;;E\makeCAB”Q?/p>
二、将用于打包的OCX控g攑֜E盘根目录下(本文档用名为evS1300.ocx的控件来q行介绍Q,如图5所C,其中evS1300.ocx是本文档q行操作的控件对象,而mfc71.dll、msvcp71.dll、msvcr71.dllq三个文仉常是进行打包时一q打包的文gQ但不是必须Q推荐一h包)Q其可在pȝ中的system32目录下找刎ͼ误行准备?/p>
三、ActiveX发布步骤
1、单?#8220;开?#8221;à“动行QRQ?#8221;à输入“cmd”à回Ràq入到操作的控g所在的目录Q如?所C:(x)
2、创建PVK文g(Uh密匙文g)Q在命o(h)行中输入“makecert -sk evS1300 evS1300.pvk -n CN=XXXXXXX公司”Q然后回车,如图7所C:(x)
3、创建CER文g(公司证书)Q在命o(h)行中输入“makecert -sk evS1300.pvk evS1300.cer”Q然后回车,如图8所C,若出?#8220;Successed”提示Q则?x)在E:\evS1300目录下生成evS1300.cer文gQ如?所C:(x)
4、创建SPC试软g出版商证明书Q在命o(h)行中输入“cert2spc evS1300.cer evS1300.spc”Q然后回车,如图10所C:(x)
5、创建INF文gQ用记录本编辑以下信?
[version]
signature="$CHINA$"
AdvancedINF=1.0
[Add.Code]
evS1300.ocx=evS1300.ocx
msvcr71.dll=msvcr71.dll
mfc71.dll=mfc71.dll
msvcp71.dll=msvcp71.dll
[evS1300.ocx]
file=thiscab
clsid={0440906E-9BD6-4F3E-B65A-39E1B339D9DA}
FileVersion=1,0,0,0
RegisterServer=yes
[msvcr71.dll]
file-win32-x86=thiscab
RegisterServer=no
DestDir=11
FileVersion=7,10,3052,4
[mfc71.dll]
file-win32-x86=thiscab
RegisterServer=no
DestDir=11
FileVersion=7,10,3077,0
[msvcp71.dll]
file-win32-x86=thiscab
RegisterServer=no
DestDir=11
FileVersion=7,10,3077,0
在evS1300.inf的内定wQ[version]和[Add.Code]Ҏ(gu)必须的,[Add.Code]的键值项的多取决于以下你所配制的多少。[msvcr71.dll]、[mfc71.dll]、[msvcp71.dll]是上面我所说不是必ȝ,只要你想把msvcr71.dll、mfc71.dll、msvcp71.dll包括在发布包里,那这么三就必须写在inf里,而这三项的具体内Ҏ(gu)固定的,可复制过d可。最为关键的是[evS1300.ocx],其中有clsid和FileVersion是evS1300.ocx的classId和versionQ这要求必须一臻I否我们发布出ȝCAB包时不能在客L(fng)自动更新下蝲安装。说到这里,那我们如何才能知道evS1300.ocx里面的classId和version呢?我在上面的必备条仉介绍到有一个用于查看ocx控g的工具ActvxDocQ对Q就是用它,我们双击q个文gq行它,此时可以看到?3所C的界面Q?/p>
在图13的界面里Q点?#8220;File”à“Open…”Q打开(zhn)所要查看的OCX控gQ如?4所C:(x)
打开了控件之后,我们在界面的双部位“Class”的下拉框里选择“”可以看到我们想要查扄FileVersion和classIdQ如?5所C:(x)
6、创建CAB文gQ在命o(h)行中输入“cabarc -s 6144 n evS1300.cab msvcr71.dll mfc71.dll msvcp71.dll evS1300.ocx evS1300.inf”Q然后回车,如图16所C:(x)
7、用Code Signing Wizard{v一个CAB文gQ首先双击运行工具集里面的signcode.exeQ或在命令行里直接输?#8220;signcode”后回车)Q系l会(x)弹出如图17所C的数字{向导Q?/p>
8、单?#8220;下一步(NQ?#8221;按钮Q来到图18所C,选择要进行数字签名的且已做成CAB包的文gevS1300.cab文g?/p>
9、选择好CAB包后单击“下一步(NQ?#8221;按钮Q在选择惌的签名类型里选择“自定议(CQ?#8221;q单?#8220;下一步(NQ?#8221;按钮Q如?9所C:(x)
10、接下来单击“从文仉择QF(tun)Q?#8221;按钮Q选择刚刚制作的evS1300.cerQ如?0所C:(x)
11、在?0中单?#8220;下一步(NQ?#8221;按钮来到?1Q然后在?1里选择“CSP中的U钥QKQ?#8221;?/p>
12、在?1中单?#8220;下一步(NQ?#8221;按钮Q然后在?2中的散列法中选择“shal”Qƈ单击“下一步(NQ?#8221;按钮?/p>
13、在“证书路径中的证书”中选择“证书路径中的所有证书,包括根证书(CQ?#8221;Q在“其它证书Q可选)”中选择“包括在以下PKCS #7 证书Q?p7bQ文件中的证书(PQ:(x)”Qƈ单击“览QRQ?#8230;”按钮选择evS1300.spc文gQ选择完后单击“下一步(NQ?#8221;按钮Q如?3所C:(x)
14、接下来在弹出的“数据描述”H口中输入公司的名称和网址q单?#8220;下一步(NQ?#8221;按钮Q如?4所C:(x)
15、现大部份工作都已完成,在接下来的一步当中是可选的操作Q其作用只是为CAB加入旉戻I此步骤完全可以不做,如图25所C:(x)
Q这里我提拱三个免费的代码签名时间戳地址Q?/p>
VeriSign: http://timestamp.verisign.com/scripts/timstamp.dll
Comodo: http://timestamp.comodoca.com/authenticode
GeoTrust/TrustCenter: http://www.trustcenter.de/codesigning/timestamp
16、完成,在图25中单?#8220;下一步(NQ?#8221;按钮便可来到数字{向导的最后一步,x作总览Q如?6所C,单击“完成”按钮便可大功告成Q如?7所C:(x)
转:(x)http://blog.csdn.net/qcdn/archive/2008/03/07/2156655.aspx
1、java.lang.OutOfMemoryError: PermGen space
JVM理两种cd的内存,堆和非堆。堆是给开发h员用的上面说的就是,是在JVM启动时创建;非堆是留lJVM自己用的Q用来存攄的信息的。它和堆不同Q运行期内GC不会(x)释放I间。如果web app用了大量的第三方jar或者应用有太多的class文g而恰好MaxPermSize讄较小Q超Z也会(x)Dq块内存的占用过多造成溢出Q或者tomcat热部|时侯不?x)清理前面加载的环境Q只?x)将context更改为新部v的,非堆存的内容׃(x)来多?/p>
PermGen space的全U是Permanent Generation space,是指内存的永久保存区域,q块内存主要是被JVM存放Class和Meta信息?Class在被Loader时就?x)被攑ֈPermGen space中,它和存放cd?Instance)的Heap区域不同,GC(Garbage Collection)不会(x)在主E序q行期对PermGen spaceq行清理Q所以如果你的应用中有很CLASS的话,很可能出现PermGen space错误Q这U错误常见在web服务器对JSPq行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大超q了jvm默认的大?4M)那么׃(x)产生此错误信息了?
一个最佳的配置例子Q?l过本h验证Q自从用此配|之后,再未出现qtomcatL的情?
set JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m
2、java.lang.OutOfMemoryError: Java heap space
W一U情冉|个补充,主要存在问题是出现在这个情况中。其默认I间(?Xms)是物理内存的1/64Q最大空?-Xmx)是物理内存的1/4。如果内存剩余不?0Q,JVM׃(x)增大堆到Xmx讄的|内存剩余过70Q,JVM׃(x)减小堆到Xms讄的倹{所以服务器的Xmx和Xms讄一般应该设|相同避免每ơGC后都要调整虚拟机堆的大小。假讄理内存无限大Q那么JVM内存的最大D操作pȝ有关Q一?2位机?.5g?g之间Q?4位的׃?x)有限制了?/p>
注意Q如果Xms过了Xmx|或者堆最大值和非堆最大值的d过了物理内存或者操作系l的最大限刉?x)引h务器启动不v来?/p>
垃圾回收GC的角?/strong>
JVM调用GC的频度还是很高的Q主要两U情况下q行垃圾回收Q?/p>
当应用程序线E空Ԍ另一个是java内存堆不xQ会(x)不断调用GCQ若q箋回收都解决不了内存堆不的问题时Q就?x)报out of memory错误。因个异常根据系l运行环境决定,所以无法预期它何时出现?/p>
Ҏ(gu)GC的机ӞE序的运行会(x)引vpȝq行环境的变化,增加GC的触发机?x)?/p>
Z避免q些问题Q程序的设计和编写就应避免垃圑֯象的内存占用和GC的开销。显C用System.GC()只能JVM需要在内存中对垃圾对象q行回收Q但不是必须马上回收Q?/p>
一个是q不能解军_存资源耗空的局面,另外也会(x)增加GC的消耗?/p>
二、JVM内存区域l成
单的说java中的堆和?/p>
java把内存分两种Q一U是栈内存,另一U是堆内?/p>
1。在函数中定义的基本cd变量和对象的引用变量都在函数的栈内存中分配;
2。堆内存用来存放由new创徏的对象和数组
在函敎ͼ代码块)中定义一个变量时Qjava在栈中个变量分配内存空_(d)当超q变量的作用域后Qjava?x)自动释放掉变量所分配的内存空_(d)在堆中分配的内存由java虚拟机的自动垃圾回收器来理
堆的优势是可以动态分配内存大,生存期也不必事先告诉~译器,因ؓ(f)它是在运行时动态分配内存的。缺点就是要在运行时动态分配内存,存取速度较慢Q?/p>
栈的优势是存取速度比堆要快Q缺Ҏ(gu)存在栈中的数据大与生存期必L定的无灉|性?/p>
java堆分Z个区QNew、Old和Permanent
GC有两个线E:(x)
新创建的对象被分配到New区,当该填满时会(x)被GC辅助U程UdOld区,当OldZ填满了会(x)触发GCȝE遍历堆内存里的所有对象。Old区的大小{于Xmx减去-Xmn
java栈存?/strong>
栈调_(d)(x)参数?UseDefaultStackSize -Xss256KQ表C每个线E可甌256k的栈I间
每个U程都有他自qStack
三、JVM如何讄虚拟内存
提示Q在JVM中如?8Q的旉是用于GC且可用的Heap size 不2Q的时候将抛出此异怿息?/p>
提示QHeap Size 最大不要超q可用物理内存的80Q,一般的要将-Xms?Xmx选项讄为相同,?Xmn?/4?Xmx倹{?
提示QJVM初始分配的内存由-Xms指定Q默认是物理内存?/64QJVM最大分配的内存?Xmx指定Q默认是物理内存?/4?/p>
默认IZ堆内存小?0%ӞJVM׃(x)增大堆直?Xmx的最大限ӞIZ堆内存大?0%ӞJVM?x)减堆直?Xms的最限制。因此服务器一般设|?Xms?Xmx相等以避免在每次GC 后调整堆的大?
提示Q假讄理内存无限大的话QJVM内存的最大D操作pȝ有很大的关系?/p>
单的说就32位处理器虽然可控内存I间?GB,但是具体的操作系l会(x)l一个限Ӟ
q个限制一般是2GB-3GBQ一般来说Windowspȝ下ؓ(f)1.5G-2GQLinuxpȝ下ؓ(f)2G-3GQ,?4bit以上的处理器׃?x)有限制?/p>
提示Q注意:(x)如果Xms过了Xmx|或者堆最大值和非堆最大值的d过了物理内存或者操作系l的最大限刉?x)引h务器启动不v来?/p>
提示Q设|NewSize、MaxNewSize相等Q?new"的大最好不要大?old"的一半,原因是old区如果不够大?x)频J的触发"? GC Q大大降低了性能
JVM使用-XX:PermSize讄非堆内存初始|默认是物理内存的1/64Q?/p>
由XX:MaxPermSize讄最大非堆内存的大小Q默认是物理内存?/4?/p>
解决Ҏ(gu)Q手动设|Heap size
修改TOMCAT_HOME/bin/catalina.bat
?#8220;echo "Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:(x)
JAVA_OPTS="-server -Xms800m -Xmx800m -XX:MaxNewSize=256m"
四、性能查工具?/strong>
定位内存泄漏Q?/p>
JProfiler工具主要用于查和跟踪pȝQ限于Java开发的Q的性能。JProfiler可以通过时时的监控系l的内存使用情况Q随时监视垃圑֛ӞU程q行状况{手D,从而很好的监视JVMq行情况?qing)其性能?/p>
1. 应用服务器内存长期不合理占用Q内存经常处于高位占用,很难回收C位;
2. 应用服务器极ZE_Q几乎每两天重新启动一ơ,有时甚至每天重新启动一ơ;
3. 应用服务器经常做Full GC(Garbage Collection)Q而且旉很长Q大U需?0-40U,应用服务器在做Full GC的时候是不响应客L(fng)交易h的,非常影响pȝ性能?
因ؓ(f)开发环境和产品环境?x)有不同Q导致该问题发生有时?x)在产品环境中发生,通常可以使用工具跟踪pȝ的内存用情况,在有些个别情况下或许某个时刻实是用了大量内存Dout of memoryQ这时应l箋跟踪看接下来是否?x)有下降Q?/p>
如果一直居高不下这肯定因为程序的原因D内存泄漏?/p>
五、不健壮代码的特征及(qing)解决办法
1、尽早释放无用对象的引用。好的办法是使用临时变量的时候,让引用变量在退出活动域后,自动讄为nullQ暗C垃圾收集器来收集该对象Q防止发生内存泄霌Ӏ?/p>
对于仍然有指针指向的实例Qjvm׃?x)回收该资?因ؓ(f)垃圾回收?x)将gؓ(f)null的对象作为垃圾,提高GC回收机制效率Q?/p>
2、我们的E序里不可避免大量用字W串处理Q避免用StringQ应大量使用StringBufferQ每一个String对象都得独立占用内存一块区域;
String str = "aaa";
String str2 = "bbb";
String str3 = str + str2;//假如执行此次之后str ,str2以后再不被调?那它?yu)׃?x)被放在内存中{待Java的gcd?E序内过多的出现q样的情况就?x)报上面的那个错?在用字W串时能使用StringBuffer׃要用String,q样可以省不开销Q?
3、尽量少用静态变量,因ؓ(f)静态变量是全局的,GC不会(x)回收的;
4、避免集中创建对象尤其是大对象,JVM?x)突焉要大量内存,q时必然?x)触发GC优化pȝ内存环境Q显C的声明数组I间Q而且甌数量q极大?/p>
q是一个案例想定供大家警戒
使用jspsmartUpload作文件上?q行q程中经常出现java.outofMemoryError的错误,
查之后发现问题:(x)lg里的代码
m_totalBytes = m_request.getContentLength();
m_binArray = new byte[m_totalBytes];
问题原因是totalBytesq个变量得到的数极大Q导致该数组分配了很多内存空_(d)而且该数l不能及(qing)旉放。解军_法只能换一U更合适的办法Q至是不会(x)引发outofMemoryError的方式解冟뀂参考:(x)http://bbs.xml.org.cn/blog/more.asp?name=hongrui&id=3747
5、尽量运用对象池技术以提高pȝ性能Q生命周期长的对象拥有生命周期短的对象时Ҏ(gu)引发内存泄漏Q例如大集合对象拥有大数据量的业务对象的时候,可以考虑分块q行处理Q然后解决一块释放一块的{略?/p>
6、不要在l常调用的方法中创徏对象Q尤其是忌讳在@环中创徏对象。可以适当的用hashtableQvector 创徏一l对象容器,然后从容器中d那些对象Q而不用每ơnew之后又丢?/p>
7、一般都是发生在开启大型文件或跟数据库一ơ拿了太多的数据Q造成 Out Of Memory Error 的状况,q时大概要计算一下数据量的最大值是多少Qƈ且设定所需最及(qing)最大的内存I间倹{?/p>
G q代标志W?/p>
y q?/p>
M ?/p>
d ?/p>
h ?在上午或下午 (1~12)
H ?在一天中 (0~23)
m ?/p>
s U?/p>
S 毫秒
E 星期
D 一q中的第几天
F 一月中W几个星期几
w 一q中W几个星?/p>
W 一月中W几个星?/p>
a 上午 / 下午 标记W?
k ?在一天中 (1~24)
K ?在上午或下午 (0~11)
z 时区
*/
1、Date—?gt;String
String sdate;
Date ddate;
……
sdate=(new SimpleDateFormat("yyyy-MM-dd")).format(ddate);
2、String—?gt;Date
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
sdf.setLenient(false);
String sdate="2006-06-06";
Date ddate;
ddate=sdf.parse(sdate);
另外Integer、Double{数据包装类型与Stringcd的相互{换ؓ(f)Q?/p>
Q以IntegerZQ?/p>
Integer—?gt;String
Integer ii;
String si;
……
si=ii.toString;
String—?gt;Intteger
Integer ii;
String si;
……
ii=Integer.valueOf(si);
字符串{换成旉?qing)时间相减?x)
1:) SimpleDateFormat formatter = new SimpleDateFormat Q?yyyy.MM.dd");
//假定?002.07.04的是合法日期其他都非法?br />
String str="2002.07.04";
ParsePosition pos = new ParsePosition(0);
Date dt=formatter.parse(str,pos);
if(dt!=null)
{
//是合法日?br />
}
else
{
//非法日期
}
2:)
两个日期相减
imp
imp
class a
{
public static void main(String[] args)
{
String s1 = "2003/08/15 17:15:30";
String s2 = "2002/09/14 14:18:37";
try{
SimpleDateFormat formatter = new SimpleDateFormat ("yyyy/MM/dd HH:mm:ss");
ParsePosition pos = new ParsePosition(0);
ParsePosition pos1 = new ParsePosition(0);
Date dt1=formatter.parse(s1,pos);
Date dt2=formatter.parse(s2,pos1);
System.out.println("dt1="+dt1);
System.out.println("dt2="+dt2);
long l = dt1.getTime() - dt2.getTime();
System.out.println("Hello World!="+l);
}catch(Exception e){
System.out.println("exception"+e.toString());
}
}
}
3:)得到2个月后的日期Q?br />
imp
imp
public class test2
{
public static void main(String args[]) throws Exception
{
String date="2001/11/30";
DateFormat dateFormat =
DateFormat.getDateInstance(DateFormat.MEDIUM);
GregorianCalendar grc=new GregorianCalendar();
grc.setTime(new Date(date));
grc.add(GregorianCalendar.MONTH,2);
System.out.println("grc="+dateFormat.format(grc.getTime()));
}
}
15.计算日期间隔
public int getDays(Date sd,Date ed){
return (ed.getTime()-sd.getTime())/(3600*24*1000)
}
16.日期加减
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
String str="20011230";
Date dt=sdf.parse(str,new ParsePosition(0));
Calendar rightNow = Calendar.getInstance();
rightNow.setTime(dt);
rightNow.add(Calendar.DATE,2);//你要加减的日?
Date dt1=rightNow.getTime();
String reStr=sdf.format(dt1,"",new FieldPosition(0));
System.out.println(reStr);
17.旉昄控制
W一U方式:(x)
<html>
<head><title>取得pȝ旉</title></head>
<body>
<%java.util.Date date=new java.util.Date();%>
现在是:(x)<%=date%>
</body>
</html>
q行l果Q?
现在是:(x)Tue Jul 31 10:32:52 CST 2001
W二U方式:(x)
<%@ page imp
<HTML>
<HEAD><TITLE>昄当前旉</TITLE></HEAD>
<BODY>
当前旉Q?
<%
Date now = new Date();
out.println(DateFormat.getTimeInstance().format(now));
%>
</BODY>
</HTML>
q行l果Q?
10:31:42 AM
W三U方式:(x)
<%
java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyyqMM月dd?);
java.util.Date currentTime_1 = new java.util.Date();
out.print(formatter.format(currentTime_1));
%>
q行l果Q?
2001q?7?1?/p>
W四U方式:(x)
<%
java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy/MM/dd HH/mm/ss");
java.util.Date currentTime_1 = new java.util.Date();
out.print(formatter.format(currentTime_1));
%>
q行l果Q?
2001/07/31 10/32/52
W三四两U方式其实是一L(fng)他可以生千变万化的格式?/p>
//比较两个旉是否相同
public class Test {
/**
* @param args
*/
private static boolean isSameDate(Date date){
Calendar calendar=Calendar.getInstance();
//int todays=calendar.get(Calendar.DAY_OF_YEAR);
// calendar.setTime(date);
// int lastDate=calendar.get(Calendar.DAY_OF_YEAR);
if(calendar.getTime().after(date)){//判断当前旉是否Z后的旉
return true;
}else{
return false;
}
}
public static void main(String[] args) throws ParseException {
// TODO Auto-generated method stub
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
sdf.setLenient(false);
String sdate="2009-08-28";
Date ddate;
ddate=sdf.parse(sdate);
Date da=new Date();
System.out.println(da);
isSameDate(da);
System.out.println(isSameDate(ddate));
}
}
下面来看看什么是 JAR 文g包吧Q?
1. JAR 文g?
JAR 文g是 Java Archive FileQ顾名思意Q它的应用是?Java 息息相关的,?Java 的一U文档格式。JAR 文g非常cM ZIP 文g——准的_(d)它就?ZIP 文gQ所以叫它文件包。JAR 文g?ZIP 文g唯一的区别就是在 JAR 文g的内容中Q包含了一?META-INF/MANIFEST.MF 文gQ这个文件是在生?JAR 文g的时候自动创建的。D个例子,如果我们h如下目录l构的一些文Ӟ(x)
==
`-- test
`-- Test.class
把它压羃?ZIP 文g test.zipQ则q个 ZIP 文g的内部目录结构ؓ(f)Q?
test.zip
`-- test
`-- Test.class
如果我们使用 JDK ?jar 命o(h)把它打成 JAR 文g?test.jarQ则q个 JAR 文g的内部目录结构ؓ(f)Q?
test.jar
|-- META-INF
| `-- MANIFEST.MF
`-- test
`--Test.class
2. 创徏可执行的 JAR 文g?
制作一个可执行?JAR 文g包来发布你的E序?JAR 文g包最典型的用法?
Java E序是由若干?.class 文gl成的。这?.class 文g必须Ҏ(gu)它们所属的包不同而分U分目录存放Q运行前需要把所有用到的包的根目录指定给 CLASSPATH 环境变量或?java 命o(h)?-cp 参数Q运行时q要到控制台下去使用 java 命o(h)来运行,如果需要直接双击运行必d Windows 的批处理文g (.bat) 或?Linux ?Shell E序。因此,许多QJava 是一U方便开发者苦了用L(fng)E序设计语言?
其实不然Q如果开发者能够制作一个可执行?JAR 文g包交l用P那么用户使用h方便了。在 Windows 下安?JRE (Java Runtime Environment) 的时候,安装文g?x)?.jar 文g映射l?javaw.exe 打开。那么,对于一个可执行?JAR 文g包,用户只需要双d?yu)可以运行程序了Q和阅读 .chm 文档一h?(.chm 文档默认是由 hh.exe 打开?。那么,现在的关键,是如何来创个可执行?JAR 文g包?
创徏可执行的 JAR 文g包,需要用带 cvfm 参数?jar 命o(h)Q同样以上述 test 目录ZQ命令如下:(x)
jar cvfm test.jar manifest.mf test
q里 test.jar ?manifest.mf 两个文gQ分别是对应的参?f ?mQ其重头戏在 manifest.mf。因创徏可执行的 JAR 文g包,光靠指定一?manifest.mf 文g是不够的Q因?MANIFEST ?JAR 文g包的特征Q可执行?JAR 文g包和不可执行?JAR 文g包都包含 MANIFEST。关键在于可执行 JAR 文g包的 MANIFESTQ其内容包含?Main-Class 一V这?MANIFEST 中书写格式如下:(x)
Main-Class: 可执行主cd?包含包名)
例如Q假设上例中?Test.class 是属?test 包的Q而且是可执行的类 (定义?public static void main(String[]) Ҏ(gu))Q那么这?manifest.mf 可以~辑如下Q?
Main-Class: test.Test <回R>
q个 manifest.mf 可以攑֜M位置Q也可以是其它的文g名,只需要有 Main-Class: test.Test 一行,且该行以一个回车符l束卛_。创Z manifest.mf 文g之后Q我们的目录l构变ؓ(f)Q?
==
|-- test
| `-- Test.class
`-- manifest.mf
q时候,需要到 test 目录的上U目录中M?jar 命o(h)来创?JAR 文g包。也是在目录树(wi)中?#8220;==”表示的那个目录中Q用如下命令:(x)
jar cvfm test.jar manifest.mf test
之后?#8220;==”目录中创Z test.jarQ这?test.jar 是执行?JAR 文g包。运行时只需要?java -jar test.jar 命o(h)卛_?
需要注意的是,创徏?JAR 文g包中需要包含完整的、与 Java E序的包l构对应的目录结构,像上例一栗?Main-Class 指定的类Q也必须是完整的、包含包路径的类名,如上例的 test.TestQ而且在没有打?JAR 文g包之前可以?java <cd> 来运行这个类Q即在上例中 java test.Test 是可以正运行的 (当然要在 CLASSPATH 正确的情况下)?
3. jar 命o(h)详解
jar 是随 JDK 安装的,?JDK 安装目录下的 bin 目录中,W(xu)indows 下文件名?jar.exeQLinux 下文件名?jar。它的运行需要用?JDK 安装目录?lib 目录中的 tools.jar 文g。不q我们除了安?JDK 什么也不需要做Q因?SUN 已经帮我们做好了。我们甚至不需要将 tools.jar 攑ֈ CLASSPATH 中?
使用不带M?jar 命o(h)我们可以看到 jar 命o(h)的用法如下:(x)
jar {ctxu}[vfm0M] [jar-文g] [manifest-文g] [-C 目录] 文g?...
其中 {ctxu} ?jar 命o(h)的子命o(h)Q每?jar 命o(h)只能包含 ctxu 中的一个,它们分别表示Q?
-c 创徏新的 JAR 文g?
-t 列出 JAR 文g包的内容列表
-x 展开 JAR 文g包的指定文g或者所有文?
-u 更新已存在的 JAR 文g?(d文g?JAR 文g包中)
[vfm0M] 中的选项可以任选,也可以不选,它们?jar 命o(h)的选项参数
-v 生成详细报告q打印到标准输出
-f 指定 JAR 文g名,通常q个参数是必ȝ
-m 指定需要包含的 MANIFEST 清单文g
-0 只存储,不压~,q样产生?JAR 文g包会(x)比不用该参数产生的体U大Q但速度更快
-M 不生所有项的清单(MANIFEST〕文Ӟ此参C(x)忽略 -m 参数
[jar-文g] 即需要生成、查看、更新或者解开?JAR 文g包,它是 -f 参数的附属参?
[manifest-文g] ?MANIFEST 清单文gQ它?-m 参数的附属参?
[-C 目录] 表示转到指定目录下去执行q个 jar 命o(h)的操作。它相当于先使用 cd 命o(h)转该目录下再执行不带 -C 参数?jar 命o(h)Q它只能在创建和更新 JAR 文g包的时候可用。
文g?... 指定一个文?目录列表Q这些文?目录是要添加到 JAR 文g包中的文?目录。如果指定了目录Q那?jar 命o(h)打包的时候会(x)自动把该目录中的所有文件和子目录打入包中?
下面举一些例子来说明 jar 命o(h)的用法:(x)
1) jar cf test.jar test
该命令没有执行过E的昄Q执行结果是在当前目录生成了 test.jar 文g。如果当前目录已l存?test.jarQ那么该文g被覆盖?
2) jar cvf test.jar test
该命令与上例中的l果相同Q但是由?v 参数的作用,昄Z打包q程Q如下:(x)
标明清单(manifest)
增加Qtest/(d= 0) (写出= 0)(存储?0%)
增加Qtest/Test.class(d= 7) (写出= 6)(压羃?14%)
3) jar cvfM test.jar test
该命令与 2) l果cMQ但在生成的 test.jar 中没有包?META-INF/MANIFEST 文gQ打包过E的信息也略有差别:(x)
增加Qtest/(d= 0) (写出= 0)(存储?0%)
增加Qtest/Test.class(d= 7) (写出= 6)(压羃?14%)
4) jar cvfm test.jar manifest.mf test
q行l果?2) 怼Q显CZ息也相同Q只是生?JAR 包中?META-INF/MANIFEST 内容不同Q是包含?manifest.mf 的内?
5) jar tf test.jar
?test.jar 已经存在的情况下Q可以查?test.jar 中的内容Q如对于 2) ?3) 生成?test.jar 分别应该此命令,l果如下Q?
对于 2)
META-INF/
META-INF/MANIFEST.MF
test/
test/Test.class
对于 3)
test/
test/Test.class
6) jar tvf test.jar
除显C?5) 中显C的内容外,q包括包内文件的详细信息Q如Q?
0 Wed Jun 19 15:39:06 GMT 2002 META-INF/
86 Wed Jun 19 15:39:06 GMT 2002 META-INF/MANIFEST.MF
0 Wed Jun 19 15:33:04 GMT 2002 test/
7 Wed Jun 19 15:33:04 GMT 2002 test/Test.class
7) jar xf test.jar
解开 test.jar 到当前目录,不显CZQ何信息,对于 2) 生成?test.jarQ解开后的目录l构如下Q?
==
|-- META-INF
| `-- MANIFEST
`-- test
`--Test.class
8) jar xvf test.jar
q行l果?7) 相同Q对于解压过E有详细信息昄Q如Q?
创徏QMETA-INF/
展开QMETA-INF/MANIFEST.MF
创徏Qtest/
展开Qtest/Test.class
9) jar uf test.jar manifest.mf
?test.jar 中添加了文g manifest.mfQ此使用 jar tf 来查?test.jar 可以发现 test.jar 中比原来多了一?manifest。这里顺便提一下,如果使用 -m 参数q指?manifest.mf 文gQ那?manifest.mf 是作为清单文?MANIFEST 来用的Q它的内容会(x)被添加到 MANIFEST 中;但是Q如果作Z般文件添加到 JAR 文g包中Q它跟一般文件无异?
10) jar uvf test.jar manifest.mf
?9) l果相同Q同时有详细信息昄Q如Q?
增加Qmanifest.mf(d= 17) (写出= 19)(压羃?-11%)
4. 关于 JAR 文g包的一些技?
1) 使用 unzip 来解?JAR 文g
在介l?JAR 文g的时候就已经说过了,JAR 文g实际上就?ZIP 文gQ所以可以用常见的一些解?ZIP 文g的工h解压 JAR 文gQ如 Windows 下的 WinZip、WinRAR {和 Linux 下的 unzip {。?WinZip ?WinRAR {来解压是因为它们解压比较直观,方便。而?unzipQ则是因为它解压时可以?-d 参数指定目标目录?
在解压一?JAR 文g的时候是不能使用 jar ?-C 参数来指定解压的目标的,因ؓ(f) -C 参数只在创徏或者更新包的时候可用。那么需要将文g解压到某个指定目录下的时候就需要先这?JAR 文g拯到目标目录下Q再q行解压Q比较麻烦。如果?unzipQ就不需要这么麻烦了Q只需要指定一?-d 参数卛_。如Q?
unzip test.jar -d dest/
2) 使用 WinZip 或?WinRAR {工具创?JAR 文g
上面提到 JAR 文g是包含?META-INF/MANIFEST ?ZIP 文gQ所以,只需要?WinZip、WinRAR {工具创建所需?ZIP 压羃包,再往q个 ZIP 压羃包中d一个包?MANIFEST 文g?META-INF 目录卛_。对于?jar 命o(h)?-m 参数指定清单文g的情况,只需要将q个 MANIFEST 按需要修改即可?
3) 使用 jar 命o(h)创徏 ZIP 文g
有些 Linux 下提供了 unzip 命o(h)Q但没有 zip 命o(h)Q所以需要可以对 ZIP 文gq行解压Q即不能创徏 ZIP 文g。如要创Z?ZIP 文gQ用带 -M 参数?jar 命o(h)卛_Q因?-M 参数表示制作 JAR 包的时候不d MANIFEST 清单Q那么只需要在指定目标 JAR 文g的地方将 .jar 扩展名改?.zip 扩展名,创徏的就是一个不折不扣的 ZIP 文g了,如将上一节的W?3) 个例子略作改动:(x)
jar cvfM test.zip test
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Collection接口
Collection是最基本的集合接口,一个Collection代表一lObjectQ即Collection的元素(ElementsQ。一些Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接承自Collection的类QJava SDK提供的类都是l承自Collection?#8220;子接?#8221;如List和Set?
所有实现Collection接口的类都必L供两个标准的构造函敎ͼ(x)无参数的构造函数用于创Z个空的CollectionQ有一个Collection参数的构造函数用于创Z个新的CollectionQ这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection?
如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个P代子Q用该q代子即可逐一讉KCollection中每一个元素。典型的用法如下Q?
Iterator it = collection.iterator(); // 获得一个P代子
while(it.hasNext()) {
Object obj = it.next(); // 得到下一个元?
}
由Collection接口z的两个接口是List和Set?
List接口
List是有序的CollectionQ用此接口能够_的控制每个元素插入的位置。用戯够用烦引(元素在List中的位置Q类g数组下标Q来讉KList中的元素Q这cM于Java的数l?
和下面要提到的Set不同QList允许有相同的元素?
除了hCollection接口必备的iterator()Ҏ(gu)外,Listq提供一个listIterator()Ҏ(gu)Q返回一个ListIterator接口Q和标准的Iterator接口相比QListIterator多了一些add()之类的方法,允许dQ删除,讑֮元素Q还能向前或向后遍历?
实现List接口的常用类有LinkedListQArrayListQVector和Stack?
LinkedListc?
LinkedList实现了List接口Q允许null元素。此外LinkedList提供额外的getQremoveQinsertҎ(gu)在LinkedList的首部或N。这些操作LinkedList可被用作堆栈QstackQ,队列QqueueQ或双向队列QdequeQ?
注意LinkedList没有同步Ҏ(gu)。如果多个线E同时访问一个ListQ则必须自己实现讉K同步。一U解x法是在创建List时构造一个同步的ListQ?
List list = Collections.synchronizedList(new LinkedList(...));
ArrayListc?
ArrayList实现了可变大的数组。它允许所有元素,包括null。ArrayList没有同步?
sizeQisEmptyQgetQsetҎ(gu)q行旉为常数。但是addҎ(gu)开销为分摊的常数Q添加n个元素需要O(n)的时间。其他的Ҏ(gu)q行旉为线性?
每个ArrayList实例都有一个容量(CapacityQ,即用于存储元素的数组的大。这个容量可随着不断d新元素而自动增加,但是增长法q没有定义。当需要插入大量元素时Q在插入前可以调用ensureCapacityҎ(gu)来增加ArrayList的容量以提高插入效率?
和LinkedList一PArrayList也是非同步的QunsynchronizedQ?
Vectorc?
Vector非常cMArrayListQ但是Vector是同步的。由Vector创徏的IteratorQ虽然和ArrayList创徏的Iterator是同一接口Q但是,因ؓ(f)Vector是同步的Q当一个Iterator被创且正在被用,另一个线E改变了Vector的状态(例如Q添加或删除了一些元素)Q这时调用Iterator的方法时抛出ConcurrentModificationExceptionQ因此必L莯异常?
Stack c?
Stackl承自VectorQ实C个后q先出的堆栈。Stack提供5个额外的Ҏ(gu)使得Vector得以被当作堆栈用。基本的push和popҎ(gu)Q还有peekҎ(gu)得到栈顶的元素,emptyҎ(gu)试堆栈是否为空QsearchҎ(gu)一个元素在堆栈中的位置。Stack刚创建后是空栈?
Set接口
Set是一U不包含重复的元素的CollectionQ即L的两个元素e1和e2都有e1.equals(e2)=falseQSet最多有一个null元素?
很明显,Set的构造函数有一个约束条Ӟ传入的Collection参数不能包含重复的元素?
h意:(x)必须心操作可变对象QMutable ObjectQ。如果一个Set中的可变元素改变了自w状态导致Object.equals(Object)=true导致一些问题?
Map接口
h意,Map没有l承Collection接口QMap提供key到value的映。一个Map中不能包含相同的keyQ每个key只能映射一个value。Map接口提供3U集合的视图QMap的内容可以被当作一lkey集合Q一lvalue集合Q或者一lkey-value映射?
HashtablecR Hashtablel承Map接口Q实C个key-value映射的哈希表。Q何非I(non-nullQ的对象都可作ؓ(f)key或者value?
d数据使用put(key, value)Q取出数据用get(key)Q这两个基本操作的时间开销为常数?
Hashtable通过initial capacity和load factor两个参数调整性能。通常~省的load factor 0.75较好地实C旉和空间的均衡。增大load factor可以节省I间但相应的查找旉增大,q会(x)影响像get和putq样的操作?
使用Hashtable的简单示例如下,?Q?Q?攑ֈHashtable中,他们的key分别?#8221;one”Q?#8221;two”Q?#8221;three”Q?
Hashtable numbers = new Hashtable();
numbers.put(“one”, new Integer(1));
numbers.put(“two”, new Integer(2));
numbers.put(“three”, new Integer(3));
要取Z个数Q比?Q用相应的keyQ?
Integer n = (Integer)numbers.get(“two”);
System.out.println(“two = ” + n);
׃作ؓ(f)key的对象将通过计算其散列函数来定与之对应的value的位|,因此M作ؓ(f)key的对象都必须实现hashCode和equalsҎ(gu)。hashCode和equalsҎ(gu)l承自根cObjectQ如果你用自定义的类当作key的话Q要相当心Q按照散列函数的定义Q如果两个对象相同,即obj1.equals(obj2)=trueQ则它们的hashCode必须相同Q但如果两个对象不同Q则它们的hashCode不一定不同,如果两个不同对象的hashCode相同Q这U现象称为冲H,冲突?x)导致操作哈希表的时间开销增大Q所以尽量定义好的hashCode()Ҏ(gu)Q能加快哈希表的操作?
如果相同的对象有不同的hashCodeQ对哈希表的操作?x)出现意想不到的l果Q期待的getҎ(gu)q回nullQ,要避免这U问题,只需要牢C条:(x)要同时复写equalsҎ(gu)和hashCodeҎ(gu)Q而不要只写其中一个?
Hashtable是同步的?
HashMapc?
HashMap和HashtablecMQ不同之处在于HashMap是非同步的,q且允许nullQ即null value和null key。,但是HashMap视ؓ(f)CollectionӞvalues()Ҏ(gu)可返回CollectionQ,其P代子操作旉开销和HashMap的容量成比例。因此,如果q代操作的性能相当重要的话Q不要将HashMap的初始化定w讑־q高Q或者load factorq低?
WeakHashMapc?
WeakHashMap是一U改q的HashMapQ它对key实行“弱引?#8221;Q如果一个key不再被外部所引用Q那么该key可以被GC回收?
ȝ
如果涉及(qing)到堆栈,队列{操作,应该考虑用ListQ对于需要快速插入,删除元素Q应该用LinkedListQ如果需要快速随问元素,应该使用ArrayList?
如果E序在单U程环境中,或者访问仅仅在一个线E中q行Q考虑非同步的c,其效率较高,如果多个U程可能同时操作一个类Q应该用同步的cR?
要特别注意对哈希表的操作Q作为key的对象要正确复写equals和hashCodeҎ(gu)?
量q回接口而非实际的类型,如返回List而非ArrayListQ这样如果以后需要将ArrayList换成LinkedListӞ客户端代码不用改变。这是针对抽象~程?
1.wait和notify
q两个方法都是Object中的Ҏ(gu),攑֜一块是因ؓ(f)他们关系非常密切.
wait是{待q个对象的同步锁,不过调用q个Ҏ(gu)必须先获得这个对象的同步?p一点很多h搞晕了.
q里先解释一下这两个Ҏ(gu),然后l出一个小例子说明.
wait:{待对象的同步锁,需要获得该对象的同步锁才可以调用这个方?否则后收C个IllegalMonitorStateException,q个是运行时异常.调用q个Ҏ(gu)?放弃了q个同步锁了.如果不带参数的waitҎ(gu)只有等别h唤醒?如果带一个参数的
化就讄{待最长时?q了q个旉即没有人唤醒这个线E也不再{待?
notify:唤醒在等待该对象同步锁的U程(只唤醒一?如果有多个在{待),但是notifyAll可以唤醒所有等待的U程,注意唤醒的时在notify之前wait的线E?之后的没有效?
q里举一个通俗的例?两个人共有一个卫生间(每次只能一个h?,他们都要L(fng)和方?他们是这L(fng)定的,轮流?W一个h先刷?然后W二个hL(fng)...
class Syn
{
public static void main(String[] args) throws Exception
{
TwoPeople.ONE.start();
TwoPeople.TWO.start();
}
}
class TwoPeople extends Thread
{
private int i=0;
static Thread ONE=new TwoPeople(1);
static Thread TWO=new TwoPeople(2);
static Object washroom=new Object();
private TwoPeople(int i){this.i=i;}
public void run(){
synchronized(washroom){
try{
if(i==1){
brush(); //1
washroom.wait(); //2
release(); //6
washroom.notify(); //7
}
else{
brush(); //3
washroom.notify(); //4
washroom.wait(); //5
release(); //8
}
}catch(InterruptedException e){e.printStackTrace();}
}
}
private void brush() {
System.out.println("People "+i+" is brushing !");
try{Thread.sleep(2000);}catch(InterruptedException e){e.printStackTrace();}
//延迟两秒看效?br />
System.out.println("People "+i+" has burshed !");
}
private void release(){
System.out.println("People "+i+" is releasing !");
try{Thread.sleep(2000);}catch(InterruptedException e){e.printStackTrace();}
//延迟两秒看效?br />
System.out.println("People "+i+" has released !");
}
};
上面的代码很?而且表明了执行顺?至于join和sleepq是下次再讨论吧.
wait,notify,sleep,join和线E同步问?l?
昨天没有旉写完q篇,今天补上,前面只说明了wait和notifyq两个方?q里讨论一下sleep和join,说实在的q两个方法比wait和notify单的?
http://blog.csdn.net/treeroot/archive/2004/11/10/175508.aspx
sleep:Thread的静态方?当前U程休眠一D|?旉C再恢复可q行状?旉C不一定就执行?q得竞争CPU?
join:q个Ҏ(gu)其实是Ҏ(gu)的wait,waitҎ(gu)一般都需要别人notify(当然也可以设|超?,但是joinҎ(gu)׃需要别人notify?一直等到这个线E死?q当于q个U程临时前告诉那些在{它的h:你们q来?)
本h不是很会(x)举例?q是两个人公用一个卫生间?q回不刷牙了,Ҏ(gu)澡吧,M能两个h同时zM?q可以,q里假设不可以吧.情况时这L(fng)QA在洗?B要等?/p>
W一U情?
B很聪明的,AzM可能?0分钟?时,我就先睡10分钟看看好了没有,没有好就再睡10分钟,最多多{?0分钟而已?
class Syn
{
public static void main(String[] args) throws Exception
{
Thread a=new Bathing();
a.start();
//B
int time=0;
while(a.isAlive()){
Thread.sleep(10000);
time+=10;
System.out.println("B has waited "+time+" minutes");
}
System.out.println("B can bath now!");
}
}
class Bathing extends Thread
{
public void run(){
bathing();
}
private void bathing() {
System.out.println("A is bathing !");
try{Thread.sleep(20000);}catch(InterruptedException e){e.printStackTrace();}
//延迟20U看效果
System.out.println("A has bathed !");
}
};
q里q同步都不需?不过B可能需要多{一D|?因ؓ(f)它可能刚好去敲门Aq没有洗?于是他又ȝ,l果刚睡下A洗完了.
W二U情?
B变得更加聪明了,q样{我不是亏了Q如果我10分钟敲一ơ门Q我可能要多{?0分钟Q但是如果我每秒敲一ơ我也没法睡呀Q于是想了一个高招,装了一个机养I当A出来的时候机兛_?x)按响门铃,q样B可以高枕无忧了?/p>
class Syn
{
public static void main(String[] args) throws Exception
{
Thread a=new Bathing();
a.start();
//B
int time=0;
a.join();
System.out.println("B can bath now!");
}
}
class Bathing extends Thread
{
public void run(){
bathing();
}
private void bathing() {
System.out.println("A is bathing !");
try{Thread.sleep(20000);}catch(InterruptedException e){e.printStackTrace();}
//延迟20U看效果
System.out.println("A has bathed !");
}
};
q样只要A一z完QB׃(x)被唤醒,q里Aq没有去notify他,但是q是间接的通知了BQ当然这里也可以用wati和notify实现Q不q就昑־不好了?/p>
class Syn
{
public static void main(String[] args) throws Exception
{
Thread a=new Bathing();
a.start();
//B
int time=0;
synchronized(a){a.wait();}
System.out.println("B can bath now!");
}
}
class Bathing extends Thread
{
public void run(){
synchronized(this){
bathing();
notify();
}
}
private void bathing() {
System.out.println("A is bathing !");
try{Thread.sleep(20000);}catch(InterruptedException e){e.printStackTrace();}
//延迟20U看效果
System.out.println("A has bathed !");
}
};
对于一般的对象p用wait和notify了,但是对于一个线E来_(d)joinҎ(gu)有时候更加方ѝ?/p>
W一节:(x)eqauls ?= =之异?/p>
1Q比较方式角度:(x)
= =是面向过E的操作W;equals是面向对象的操作W?/p>
= =不属于Q何类Qequals则是Mc(在Java中)的一个方法;
我们可以1QPrimitive1 (基本cd)= = Primitive2(基本cd)Q?/p>
2QObject Reference1(对象引用)= = Object Reference2(对象引用)
3QObject Reference1 (对象引用) .equals(Object Reference2 (对象引用))
q三U比?/p>
但却不能Primitive1 (基本cd).equals( Primitive2(基本cd))Q?/p>
对于基本cdQ没有面向对象中发送消息一_(d)自然也不?x)?/p>
Ҏ(gu)成员?/p>
2Q比较目的角?
1Q?nbsp; 如果要比较两个基本类型是否相{,L(fng)= =Q?/p>
2Q?nbsp; 如果要比较两个对象引用是否相{,L(fng)= =Q?/p>
3Q?nbsp; 如果要比较两个对象(逻辑上)是否一_(d)L(fng)equalsQ?/p>
W二节:(x)对两个对象(逻辑上)是否一致的阐释Q?/p>
有h?x)?在C++? 比较两个对象相等不是也可以用==吗?我知道?zhn)是指q算W重载,但是很遗憾,Java中不支持q算W重载(java中亦有重载过q算W,他们?#8220;+”Q?#8220;+=”Q不q也仅此两个Q而且是内|实现的Q;所以,对象的是否相{的比较q䆾责Q׃?nbsp; equals()来实??nbsp;
q个“逻辑?#8221;其实取决于人类的看法,实际开发中Q就取决于用L(fng)需求;
有h?x)有看法Q?#8220;取决于hcȝ看法”太过宽泛和不严肃Q如果某两g
风牛马不相及(qing)的事物也相等Qequals是否也能作出q样的比较呢Q我们说可以?/p>
下面q个例子说明了这一点:(x)
class Horse {
String Type;
int Legs;
//相等的标准:(x)腿的数目相等
public boolean equals(Object o){
if(this.Legs==((Cattle)o).Legs){
return true;
}
return false;
}
public Horse(String Type,int legs){
this.Type=Type;
this.Legs=legs;
}
}
class Cattle
{
String Type;
int Legs;
//相等的标准:(x)腿的数目相等
public Cattle(String Type,int legs){
this.Type=Type;
this.Legs=legs;
}
public boolean equals(Object o){
if(this.Legs==((Horse)o).Legs){
return true;
}
return false;
}
}
public class EqualsTest{
public static void main(String[] args)
{
Cattle c=new Cattle("I'm the Cattle",4);
Horse h=new Horse("I'm the Horse",4);
if(c.equals(h)){
System.out.println(c.Type);
System.out.println(h.Type);
System.out.println("Cattle Equals Horse");
}
}
}
输出l果Q?I'm the Cattle"
"I'm the Horse"
"Cattle Equals Horse"
(zhn)瞧瞧:(x)牛果真等于了马,Z相等Q因为我们定义的相等标准是:(x)腿的数目相等Q?zhn)会(x)说Q?#8220;q太滑稽”Q是滑稽Q可q是人类的看法,计算机可没有滑稽的概念,当然也没?#8220;不滑E?#8221;的概念,我们定义了什么相{标准,他就t踏实实的ؓ(f)我们实现了;
所以说Q相{标准(即需求)一定要定好Q否则,滑稽的事可就多了
W三节:(x)equals()~vQ?/p>
equals()是每个对象与生俱来的Ҏ(gu)Q因为所有类的最l基cd是Object(除去Object本n)Q而equals()是Object的方法之一?/p>
我们不妨观察一下Object中equals()的source code:
public boolean equals(Object obj) {
return (this == obj);
}
注意 “return (this == obj)”
this与obj都是对象引用Q而不是对象本w。所以equals()的缺省实现就是比?/p>
对象引用是否一_(d)Z要如此实现呢Q?前面我们说过Q对象是否相{,是由我们的需求决定的Q世界上的类千奇百怪(当然Q这些类都是我们Ҏ(gu)模拟现实世界而创造的Q,虽然Object是他们共同的先Q可他又怎能知道他的子孙cL较相{的标准呢?但是他明白,M一个对象,自己L{于自己的,何谓“自己L{于自己”呢,又如何判?#8220;自己L{于自己”呢?一个对象在内存中只有一份,但他的引用却可以有无I多个,“对象自己的引?=对象自己的引?”Q不p判断“自己L{于自己”吗?所以缺省实现实现自然也是
“return (this == obj)”Q?/p>
而到了我们自q写的c,对象相等的标准由我们立Q于是就不可避免的要覆写
l承而来的public boolean equals(Object obj)Q?/p>
如果(zhn)有q编覆写qequalsQ)的经验(没有q也不要紧)Q请(zhn)思考一个问题:(x)
“两个对象Q逻辑上)是否一?#8221;实际上是比较什么?没错Q或许?zhn)已脱口而出Q?/p>
是对象的属性(即fieldQ或U数据成员)的比较。方法是不可比较的哦。(q个问题是不是有些弱智呢Q哈哈)
W四节:(x)对一个推论的思?/p>
推论如下Q一a以蔽之:(x)Ʋ比较栈中数据是否相{,L(fng)= =Q?/p>
Ʋ比较堆中数据是否相{,L(fng)equalsQ?
因ؓ(f)Q根Q基本类型,Q根Q对象引用都在栈中; 而对象本w在堆中Q?/p>
q句话又对又不对Q问题出在哪Q就?#8220;数据”二字Q先看栈中,数据或ؓ(f)基本cdQ或为对象引用,?=比较当然没错Q但是堆中呢Q对象不是堆中吗Q不是应该用equals比较吗?可是Q我们比较的是堆?#8220;数据”Q堆中有对象Q对象由什么构成呢Q可能是对象引用Q可能是基本cdQ或两者兼而有之。如果我们要比较他们Q该用什么呢Q用”equals()”?不对吧,只能?#8221;= =”!所以正的l论是:(x)Ʋ比较栈中数据是否相{,L(fng)= =Q?Ʋ比较堆中数据是否相{,L(fng)equalsQ?/p>
因ؓ(f)Q根Q基本类型,Q根Q对象引用都在栈中(所?#8220;?#8221;Q指未被M其他对象所包含Q; 而对象本w在堆中?/p>
import java.lang.*;
import java.text.*;
import java.util.*;
public class timeformat{
public timeformat(){
}
static public String getChineseFormatTime(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
return sdf.format(new Date());
}
static public String getSimpleFormatTime(){
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm", Locale.US);
return sdf.format(new Date());
}
}