2008年12月1日
#
public class QuenDemo {
public static void main(String[] args){
//public class Queue extends Collection
Queue<Integer> queue=new LinkedList<Integer>();
Random rand = new Random(47);
for(int i=0;i<10;i++){
queue.offer(rand.nextInt(i+10));
}
System.out.println("1111"+queue.toString());
printQ(queue);
//public class LinkedList extends AbstractSequentialList implements List,Queue,Cloneable,Serializable
Queue<Character> qc=new LinkedList<Character>();
for(char c:"guoxzh".toCharArray()){
qc.offer(c);
System.out.println("qc=="+qc.toString());
}
printQ(qc);
}
public static void printQ(Queue queue){
while(queue.peek()!=null){
//peek和element都是在不移除的情況下返回對頭,但是peek在隊(duì)列為空的情況下返回null,element方法會(huì)拋出NoSuchElementException異常
System.out.println(queue.remove());
//remove和poll方法都是在移除并返回對頭,但是poll在為空時(shí)返回null,而remove會(huì)拋出NoSucheElementException異常
System.out.println("2222"+queue.toString());
}
}
}
package src;
import java.io.UnsupportedEncodingException;
public class ChangeCharset {
/** 7位ASCII字符,也叫作ISO646-US、Unicode字符集的基本拉丁塊 */
public static final String US_ASCII = "US-ASCII";
/** ISO 拉丁字母表 No.1,也叫作 ISO-LATIN-1 */
public static final String ISO_8859_1 = "ISO-8859-1";
/** 8 位 UCS 轉(zhuǎn)換格式 */
public static final String UTF_8 = "UTF-8";
/** 16 位 UCS 轉(zhuǎn)換格式,Big Endian(最低地址存放高位字節(jié))字節(jié)順序 */
public static final String UTF_16BE = "UTF-16BE";
/** 16 位 UCS 轉(zhuǎn)換格式,Little-endian(最高地址存放低位字節(jié))字節(jié)順序 */
public static final String UTF_16LE = "UTF-16LE";
/** 16 位 UCS 轉(zhuǎn)換格式,字節(jié)順序由可選的字節(jié)順序標(biāo)記來標(biāo)識(shí) */
public static final String UTF_16 = "UTF-16";
/** 中文超大字符集 */
public static final String GBK = "GBK";
/**
* 將字符編碼轉(zhuǎn)換成US-ASCII碼
*/
public String toASCII(String str) throws UnsupportedEncodingException{
return this.changeCharset(str, US_ASCII);
}
/**
* 將字符編碼轉(zhuǎn)換成ISO-8859-1碼
*/
public String toISO_8859_1(String str) throws UnsupportedEncodingException{
return this.changeCharset(str, ISO_8859_1);
}
/**
* 將字符編碼轉(zhuǎn)換成UTF-8碼
*/
public String toUTF_8(String str) throws UnsupportedEncodingException{
return this.changeCharset(str, UTF_8);
}
/**
* 將字符編碼轉(zhuǎn)換成UTF-16BE碼
*/
public String toUTF_16BE(String str) throws UnsupportedEncodingException{
return this.changeCharset(str, UTF_16BE);
}
/**
* 將字符編碼轉(zhuǎn)換成UTF-16LE碼
*/
public String toUTF_16LE(String str) throws UnsupportedEncodingException{
return this.changeCharset(str, UTF_16LE);
}
/**
* 將字符編碼轉(zhuǎn)換成UTF-16碼
*/
public String toUTF_16(String str) throws UnsupportedEncodingException{
return this.changeCharset(str, UTF_16);
}
/**
* 將字符編碼轉(zhuǎn)換成GBK碼
*/
public String toGBK(String str) throws UnsupportedEncodingException{
return this.changeCharset(str, GBK);
}
/**
* 字符串編碼轉(zhuǎn)換的實(shí)現(xiàn)方法
* @param str 待轉(zhuǎn)換編碼的字符串
* @param newCharset 目標(biāo)編碼
* @return
* @throws UnsupportedEncodingException
*/
public String changeCharset(String str, String newCharset)
throws UnsupportedEncodingException {
if (str != null) {
//用默認(rèn)字符編碼解碼字符串。
byte[] bs = str.getBytes();
//用新的字符編碼生成字符串
return new String(bs, newCharset);
}
return null;
}
/**
* 字符串編碼轉(zhuǎn)換的實(shí)現(xiàn)方法
* @param str 待轉(zhuǎn)換編碼的字符串
* @param oldCharset 原編碼
* @param newCharset 目標(biāo)編碼
* @return
* @throws UnsupportedEncodingException
*/
public String changeCharset(String str, String oldCharset, String newCharset)
throws UnsupportedEncodingException {
if (str != null) {
//用舊的字符編碼解碼字符串。解碼可能會(huì)出現(xiàn)異常。
byte[] bs = str.getBytes(oldCharset);
//用新的字符編碼生成字符串
return new String(bs, newCharset);
}
return null;
}
public static void main(String[] args) throws UnsupportedEncodingException {
ChangeCharset test = new ChangeCharset();
String str = "This is a 中文的 String!";
System.out.println("str: " + str);
String gbk = test.toGBK(str);
System.out.println("轉(zhuǎn)換成GBK碼: " + gbk);
System.out.println();
String ascii = test.toASCII(str);
System.out.println("轉(zhuǎn)換成US-ASCII碼: " + ascii);
gbk = test.changeCharset(ascii,ChangeCharset.US_ASCII, ChangeCharset.GBK);
System.out.println("再把ASCII碼的字符串轉(zhuǎn)換成GBK碼: " + gbk);
System.out.println();
String iso88591 = test.toISO_8859_1(str);
System.out.println("轉(zhuǎn)換成ISO-8859-1碼: " + iso88591);
gbk = test.changeCharset(iso88591,ChangeCharset.ISO_8859_1, ChangeCharset.GBK);
System.out.println("再把ISO-8859-1碼的字符串轉(zhuǎn)換成GBK碼: " + gbk);
System.out.println();
String utf8 = test.toUTF_8(str);
System.out.println("轉(zhuǎn)換成UTF-8碼: " + utf8);
gbk = test.changeCharset(utf8,ChangeCharset.UTF_8, ChangeCharset.GBK);
System.out.println("再把UTF-8碼的字符串轉(zhuǎn)換成GBK碼: " + gbk);
System.out.println();
String utf16be = test.toUTF_16BE(str);
System.out.println("轉(zhuǎn)換成UTF-16BE碼:" + utf16be);
gbk = test.changeCharset(utf16be,ChangeCharset.UTF_16BE, ChangeCharset.GBK);
System.out.println("再把UTF-16BE碼的字符串轉(zhuǎn)換成GBK碼: " + gbk);
}
}
JAVA里面關(guān)于byte數(shù)組和String之間的轉(zhuǎn)換問題
把byte轉(zhuǎn)化成string,必須經(jīng)過編碼。
例如下面一個(gè)例子:
import java.io.UnsupportedEncodingException;
public class test{
public static void main(String g[]) {
String s = "12345abcd";
byte b[] = s.getBytes();
String t = b.toString();
System.out.println(t);
}
}
輸出字符串的結(jié)果和字符串s不一樣了.
經(jīng)過以下方式轉(zhuǎn)碼就可以正確轉(zhuǎn)換了:
public class test{
public static void main(String g[]) {
String s = "12345abcd";
byte b[] = s.getBytes();
try {
String t = new String(b);
System.out.print(t);
} catch (Exception e) {
e.printStackTrace();
}
}
}
引用:
String str = "String";
byte[] byte1 = str.getBytes();
String str1 = new String(byte1);
byte[] byte2 = str1.getBytes();
String str2 = new String(byte2);
System.out.println("str<<<" + str);
System.out.println("byte1<<<" + byte1);
System.out.println("str1<<<" + str1);
System.out.println("byte2<<<" + byte2);
System.out.println("str2<<<" + str2);
-------------------------------------
輸出結(jié)果
str<<<String
byte1<<<[B@192d342
str1<<<String
byte2<<<[B@6b97fd
str2<<<String
想請教為什么兩個(gè)byte輸出的不一樣呢?
String str = "String";
byte[] byte1 = str.getBytes();
String str1 = new String(byte1);
byte[] byte2 = str1.getBytes();
----------
注意byte1是str得到的byte數(shù)組,而byte2是另一個(gè)字符串str1得到的數(shù)組
他們本身也是兩個(gè)對象
直接打印實(shí)際上調(diào)用的是toString()方法,而toString()的默認(rèn)實(shí)現(xiàn)是打印對象類型+hashCode()
[B表示byte數(shù)組 @表示之后的是地址 后面跟著的是hashCode,其實(shí)就是其虛擬機(jī)地址
從大的方面來講,JVM的內(nèi)存模型分為兩大塊:
永久區(qū)內(nèi)存( Permanent space)和堆內(nèi)存(heap space)。
棧內(nèi)存(stack space)一般都不歸在JVM內(nèi)存模型中,因?yàn)闂?nèi)存屬于線程級(jí)別。
每個(gè)線程都有個(gè)獨(dú)立的棧內(nèi)存空間。
Permanent space里存放加載的Class類級(jí)對象如class本身,method,field等等。
heap space主要存放對象實(shí)例和數(shù)組。
heap space由Old Generation和NewGeneration組成,OldGeneration存放生命周期長久的實(shí)例對象,而新的對象實(shí)例一般放在NewGeneration。
New Generation還可以再分為Eden區(qū)(圣經(jīng)中的伊甸園)、和Survivor區(qū),新的對象實(shí)例總是首先放在Eden區(qū),Survivor區(qū)作為Eden區(qū)和Old區(qū)的緩沖,可以向Old區(qū)轉(zhuǎn)移活動(dòng)的對象實(shí)例。
一般,我們常見的OOM(out of memory)內(nèi)存溢出異常,就是堆內(nèi)存空間不足以存放新對象實(shí)例時(shí)導(dǎo)致。
永久區(qū)內(nèi)存溢出相對少見,一般是由于需要加載海量的Class數(shù)據(jù),超過了非堆內(nèi)存的容量導(dǎo)致。通常出現(xiàn)在Web應(yīng)用剛剛啟動(dòng)時(shí),因此Web應(yīng)用推薦使用預(yù)加載機(jī)制,方便在部署時(shí)就發(fā)現(xiàn)并解決該問題。
棧內(nèi)存也會(huì)溢出,但是更加少見。
堆內(nèi)存優(yōu)化:
調(diào)整JVM啟動(dòng)參數(shù)-Xms -Xmx -XX:newSize -XX:MaxNewSize,如調(diào)整初始堆內(nèi)存和最大對內(nèi)存 -Xms256M -Xmx512M。 或者調(diào)整初始New Generation的初始內(nèi)存和最大內(nèi)存-XX:newSize=128M -XX:MaxNewSize=128M。
永久區(qū)內(nèi)存優(yōu)化:
調(diào)整PermSize參數(shù) 如 -XX:PermSize=256M-XX:MaxPermSize=512M。
棧內(nèi)存優(yōu)化:
調(diào)整每個(gè)線程的棧內(nèi)存容量 如 -Xss2048K
最終,一個(gè)運(yùn)行中的JVM所占的內(nèi)存= 堆內(nèi)存 + 永久區(qū)內(nèi)存 + 所有線程所占的棧內(nèi)存總和 。
財(cái)務(wù)公司的背景:
財(cái)務(wù)公司有兩種模式:
1.美國模式財(cái)務(wù)公司是以搞活商品流通、促進(jìn)商品銷售為特色的非銀行金融機(jī)構(gòu),它依附于制造商,是一些大型耐用品而設(shè)立的受控子公司,這類財(cái)務(wù)公司主要是為零售商提供融資服務(wù)的,主要分布在美國、加拿大和德國。
2.英國模式財(cái)務(wù)公司基本上依附于商業(yè)銀行,其組建的目的在于規(guī)避政府對商業(yè)銀行的監(jiān)管,因?yàn)檎?guī)定,商業(yè)銀行不得從事證券投資業(yè)務(wù),而財(cái)務(wù)公司不屬于銀行,所以不受此限制,這種模式主要分布在英國、日本和中國香港。
中國財(cái)務(wù)公司概況
財(cái)務(wù)公司又稱金融公司,是為了企業(yè)技術(shù)改造,新產(chǎn)品開發(fā)及產(chǎn)品銷售提供金融服務(wù)的,以中長期金融業(yè)務(wù)為主的非銀行機(jī)構(gòu),各國的名稱不同,業(yè)務(wù)內(nèi)容也不一樣。
財(cái)務(wù)公司是中國企業(yè)體制改革和融資體制改革的產(chǎn)物,國家為了增強(qiáng)國有大中型企業(yè)的活力,盤活企業(yè)內(nèi)部資金,增強(qiáng)企業(yè)集團(tuán)的融資能力,支持企業(yè)集團(tuán)的發(fā)展,促進(jìn)產(chǎn)業(yè)結(jié)構(gòu)和產(chǎn)品結(jié)果的調(diào)整,以及探索具有中國特色的產(chǎn)品資本與金融資本相結(jié)合的道路,于1987年成立了中國第一家企業(yè)集團(tuán)財(cái)務(wù)公司,即東風(fēng)汽車工業(yè)集團(tuán)財(cái)務(wù)公司。
財(cái)務(wù)公司---公司主體
財(cái)務(wù)公司是根據(jù)《公司法》和《企業(yè)集團(tuán)財(cái)務(wù)公司管理辦法》設(shè)立的,為企業(yè)集團(tuán)成員單位技術(shù)改造、新產(chǎn)品開發(fā)及產(chǎn)品銷售提供金融服務(wù),以中長期金融業(yè)務(wù)為主的非銀行機(jī)構(gòu)。
財(cái)務(wù)公司一般分企業(yè)附屬財(cái)務(wù)公司和非企業(yè)附屬財(cái)務(wù)公司,企業(yè)附屬財(cái)務(wù)公司由企業(yè)設(shè)立,為本企業(yè)服務(wù),但是服務(wù)范圍不僅局限于本企業(yè);非企業(yè)附屬財(cái)務(wù)公司包括銀行附屬財(cái)務(wù)公司、引起合資財(cái)務(wù)公司和獨(dú)立財(cái)務(wù)公司。
1.銀行附屬財(cái)務(wù)公司是由銀行控股,因規(guī)避監(jiān)管、實(shí)現(xiàn)金融創(chuàng)新和彌補(bǔ)銀行的不足而設(shè)立的,同時(shí)也為企業(yè)和個(gè)人提供金融服務(wù)。
2.銀行合資財(cái)務(wù)公司是銀行和企業(yè)出于金融創(chuàng)新規(guī)避監(jiān)管或促進(jìn)產(chǎn)融合作的考慮而設(shè)立,為企業(yè)和個(gè)人提供金融服務(wù),
3.獨(dú)立財(cái)務(wù)公司一般是沒有母公司的財(cái)務(wù)公司,規(guī)模較小,比較靈活,在某一方面提供融資服務(wù)。
財(cái)務(wù)公司的業(yè)務(wù)范圍
1.經(jīng)中國人民銀行批準(zhǔn),中國財(cái)務(wù)公司可從事下列部分或全部業(yè)務(wù):
2.吸收成員單位3個(gè)月以上定期存款。
3.發(fā)行財(cái)務(wù)公司債券。
4.同業(yè)拆借。
5.對成員單位辦理貸款及融資租賃。
6.辦理集團(tuán)成員單位產(chǎn)品的消費(fèi)信貸、買方信貸及融資租賃。
7.辦理成員單位商業(yè)匯票的承兌及貼現(xiàn)。
8.辦理成員單位的委托貸款及委托投資。
9.有價(jià)證券、金融機(jī)構(gòu)股權(quán)及成員單位股權(quán)投資。
10.承銷成員單位的企業(yè)債券。
11.對成員單位辦理財(cái)務(wù)顧問、信用鑒證及其他咨詢代理業(yè)務(wù)。
12.對成員單位提供擔(dān)保。
13.境外外匯借款。
14.經(jīng)中國人民銀行批準(zhǔn)的其他業(yè)務(wù)。
財(cái)務(wù)公司的主要作用
1.業(yè)務(wù)范圍比較廣,但是以企業(yè)集團(tuán)為限。
主要業(yè)務(wù)有存款、貸款、結(jié)算、擔(dān)保和代理等一般銀行業(yè)務(wù),還可以經(jīng)人民銀行批準(zhǔn),開展證券、信托投資等業(yè)務(wù)。
2.資金來源于集團(tuán)公司,用于集團(tuán)公司,對集團(tuán)公司的依附性強(qiáng),
財(cái)務(wù)公司的資金主要來源于兩個(gè)方面:a、集團(tuán)公司和集團(tuán)成員公司投入的資本金;b、集團(tuán)公司成員企業(yè)在財(cái)務(wù)公司的存款。
3.接受企業(yè)集團(tuán)和人民銀行的雙重監(jiān)管。
財(cái)務(wù)公司是企業(yè)內(nèi)部的金融機(jī)構(gòu),期股東大都是集團(tuán)公司成員企業(yè),因而其景榮活動(dòng)必然受到集團(tuán)公司的監(jiān)督,同時(shí),財(cái)務(wù)公司所從事的是金融業(yè)務(wù),其金融活動(dòng)必須接受人民銀行監(jiān)管
4.堅(jiān)持服務(wù)與效益相結(jié)合、服務(wù)優(yōu)先的經(jīng)營原則。雖然財(cái)務(wù)公司作為獨(dú)立的法人,但是是企業(yè)集團(tuán)內(nèi)部的機(jī)構(gòu),且集團(tuán)公司成員企業(yè)大都是財(cái)務(wù)公司的股東,所以財(cái)務(wù)公司在經(jīng)營中一般都應(yīng)較好地處理服務(wù)與效益的關(guān)系,在堅(jiān)持為集團(tuán)公司成員企業(yè)提供良好金融服務(wù)的前提下,努力實(shí)現(xiàn)利潤的最大化,
財(cái)務(wù)公司的作用
1.在資金管理方面和使用上,促使企業(yè)從粗放型向集約型轉(zhuǎn)變,
沒有財(cái)務(wù)公司之前,集團(tuán)公司成員企業(yè)不能直接發(fā)生信貸關(guān)系,有些單位資金閑置,有些單位資金緊張,財(cái)務(wù)公司成立以后,成員單位成為財(cái)務(wù)公司的股東,在一定程度上集中了各成員單位的資本來進(jìn)行一體化經(jīng)營,財(cái)務(wù)公司應(yīng)用金融手段將集團(tuán)公司內(nèi)企業(yè)的閑散資金集中起來,統(tǒng)籌安排使用,這樣不僅可以加快集團(tuán)成員企業(yè)間資金結(jié)算的速度,而且總整體上降低了集團(tuán)財(cái)務(wù)費(fèi)用,提高就然公司資金的使用效率,加速集團(tuán)公司資產(chǎn)一體化經(jīng)營的進(jìn)程,
2.財(cái)務(wù)公司以資金為紐帶,以服務(wù)為手段,增強(qiáng)了集團(tuán)公司的凝聚力。
股本金將成員單位聯(lián)接在一起,另一方面財(cái)務(wù)公司吸納的資金又成為集團(tuán)公司企業(yè)信貸資金的一個(gè)來源,從而集團(tuán)公司成員企業(yè)進(jìn)一步緊密的聯(lián)結(jié)在一起,形成了一種相互支持,相互促進(jìn),共同發(fā)展的局面。
3.及時(shí)解決了企業(yè)集團(tuán)急需的資金,保證企業(yè)生產(chǎn)經(jīng)營的正常進(jìn)行。
4.增強(qiáng)了企業(yè)集團(tuán)的融資功能,促進(jìn)了集團(tuán)公司的發(fā)展壯大,
5.有利于打破現(xiàn)有銀行體制資金規(guī)模按行政區(qū)域分割的局面,促進(jìn)大集團(tuán)公司跨地域、跨行業(yè)發(fā)展,
6.促進(jìn)了金融業(yè)的競爭,有利于金融機(jī)構(gòu)提高服務(wù)質(zhì)量和效益,有利于金融體制改革的深化。
1、“我請客”:覺得我們常用pay這個(gè)詞,如Let me pay it for you。這里列舉三種說法:I am buying;This is on me;This is all my bill。
2、“收買某人”:有個(gè)比較正式的詞叫bribe,名詞時(shí)為“賄賂”的意思,動(dòng)詞時(shí)就有“收買”之意。既然提到了“買”,那么我們能不能用上buy呢?當(dāng)然,那就是buy sb off。
3、“向前看!”:我們會(huì)說Look forward!而美語里有個(gè)更貼切的說法是Eyes front!“眼睛朝前”,是不是很生動(dòng)?
4、“頭等大事”:你會(huì)怎么翻譯呢?The most important thing嗎?看這個(gè)吧“It's on the top of my list”。
5、“看在主的份上,你就……”:兩種說法,其一是For the love of God,另外For God's sake(sake的意思是緣故、關(guān)系)二者之中,后者更常用
6、“我不是傻子!”:I am not a fool?對,語法完全正確。但再看這個(gè)I am no fool。比上面的只少兩個(gè)字母,但是不是感覺不一樣?同樣的道理,我們常說I have no idea,而不常說I dont have any idea。
7、short hairs:是說“短頭發(fā)”嗎?呵呵,它就是我們說的“小辮子”!
8、one-time thing:帥哥跟一美女過了一夜,回來后室友問帥哥:Do you really love her?帥哥回答:Oh, it was just a one-time thing!那么one-time thing是什么呢?我就不羅嗦嘍!
9、She knew red was her color。“她知道紅色是她的顏色”?恰當(dāng)?shù)姆g是:她知道自己和紅色很相配。Then, what's your color?
10、“停電”:No electricity?恩,夠直白!其實(shí)提到“電”,老外更多是用power,停電就可以是Ther is a power failure或Power goes out
有一次編網(wǎng)頁的時(shí)候,把base 標(biāo)簽給刪掉了,超鏈接怎么也行不通,老是路徑不對,原來是base 標(biāo)簽在做怪:
<base>標(biāo)記定義了文檔的基礎(chǔ)URL地址,在文檔中所有的相對地址形式的URL都是相對于這里定義的URL而言的。一篇文檔中的<base>標(biāo)記不能多于一個(gè),必須放于頭部,并且應(yīng)該在任何包含URL地址的語句之前。
(1)href 屬性
href屬性指定了文檔的基礎(chǔ)URL地址,該屬性在<base>標(biāo)記中是必須存在的。
例如:如果希望將文檔的基礎(chǔ)URL定義為“www.abc.com”,則可以使用如下語句:
<base href = "www.abc.com"> 當(dāng)定義了基礎(chǔ)URL地址之后,文檔中所有引用的URL地址都從該基礎(chǔ)URL地址開始,例如,對于上面的語句,如果文檔中一個(gè)超級(jí)鏈接指向gsl/welcome.htm,則它實(shí)際上指向的是如下URL地址:www.abc.com/gsl/welcome.htm
(2)target
target屬性同框架一起使用,它定義了當(dāng)文檔中的鏈接被點(diǎn)擊后,在哪一個(gè)框架中展開頁面。如果文檔中超級(jí)鏈接沒有明確指定展開頁面的目標(biāo)框架集,則就使用這里定義的地址代替。常用的target的屬性值有:
_blank,表明在新窗口中打開鏈接指向的頁面。
_self,在當(dāng)前文檔的框架中打開頁面。
_parent,在當(dāng)前文檔的父窗口中打開頁面。
_top,在鏈接所在的完整窗口中展開頁面。
1、增加一個(gè)虛似硬盤
如果是在vmware里面安裝的windows系統(tǒng),添加個(gè)硬盤很容易,
(1)先打開要添加硬盤的虛擬系統(tǒng)(不要啟動(dòng)該系統(tǒng)),選擇虛擬機(jī)菜單---設(shè)置-----選添加,
(2)然后在彈出添加硬件向?qū)Т翱谥?-----選擇硬盤-------一路next就好了,后面的操作和新建一個(gè)虛擬機(jī)的時(shí)候配置硬盤是一樣的。
(3)添加了新的硬盤后,啟動(dòng)windows進(jìn)到系統(tǒng)中,在控制面板中找“管理工具”->“計(jì)算機(jī)管理”,然后選“磁盤管理”,添加新磁盤就好了。
其實(shí)很簡單的..如果想繼續(xù)給VMware增加硬盤的話,重復(fù)上述動(dòng)作。
2、改變原虛擬硬盤的大小
界面中并沒有提供增加硬盤容量的方法。
只能在命令行形式下執(zhí)行。
安裝所在盤的c:\Program Files\VMware\VMware Workstation下有一個(gè)vmware-vdiskmanager.exe,就是它。
命令參數(shù)如下:
------------------------------------------------------------------
Usage: vmware-vdiskmanager.exe OPTIONS <disk-name> | <mount-point>
Offline disk manipulation utility
Options:
-c : create disk; need to specify other create options
-d : defragment the specified virtual disk
-k : shrink the specified virtual disk
-n <source-disk> : rename the specified virtual disk; need to
specify destination disk-name
-p : prepare the mounted virtual disk specified by
the drive-letter for shrinking
-q : do not log messages
-r <source-disk> : convert the specified disk; need to specify
destination disk-type
-x <new-capacity> : expand the disk to the specified capacity
Additional options for create and convert:
-a <adapter> : (for use with -c only) adapter type (ide, buslogic o
r lsilogic)
-s <size> : capacity of the virtual disk
-t <disk-type> : disk type id
Disk types:
0 : single growable virtual disk
1 : growable virtual disk split in 2Gb files
2 : preallocated virtual disk
3 : preallocated virtual disk split in 2Gb files
The capacity can be specified in sectors, Kb, Mb or Gb.
The acceptable ranges:
ide adapter : [100.0Mb, 950.0Gb]
scsi adapter: [100.0Mb, 950.0Gb]
ex 1: vmware-vdiskmanager.exe -c -s 850Mb -a ide -t 0 myIdeDisk.vmdk
ex 2: vmware-vdiskmanager.exe -d myDisk.vmdk
ex 3: vmware-vdiskmanager.exe -r sourceDisk.vmdk -t 0 destinationDisk.vm
dk
ex 4: vmware-vdiskmanager.exe -x 36Gb myDisk.vmdk
ex 5: vmware-vdiskmanager.exe -n sourceName.vmdk destinationName.vmdk
ex 6: vmware-vdiskmanager.exe -k myDisk.vmdk
ex 7: vmware-vdiskmanager.exe -p <mount-point>
(A virtual disk first needs to be mounted at <mount-point>)
-----------------------------------------------------------------
其中的-x參數(shù)就是用來擴(kuò)容的……
如這個(gè):vmware-vdiskmanager.exe -x 36Gb myDisk.vmdk
解析: vmware-vdiskmanager.exe -x 大小 虛擬硬盤文件
-------------------------------------------------------
我的執(zhí)行過程:
D:\Program files\VMware\VMware Workstation>vmware-vdiskmanager.exe -x 12GB "F:\Windows Server 2003 Enterprise Edition\Windows Server 2003 Enterprise Edition.vmdk"
==================================================================
總結(jié)一下:
1。文件名應(yīng)該用雙引號(hào)括起來。
2。vmdk文件名要連同路徑。
3。GB,MB,別忘了B。
什么是金融債券?金融債券有哪些種類?
金融債券是由銀行和非銀行金融機(jī)構(gòu)發(fā)行的
債券。在英、美等歐美國家,金融機(jī)構(gòu)發(fā)行的債券歸類于
公司債券。在我國及日本等國家,金融機(jī)構(gòu)發(fā)行的債券稱為金融債券。 金融債券能夠較有效地解決銀行等金融機(jī)構(gòu)的資金來源不足和期限不匹配的矛盾。
一般來說,銀行等金融機(jī)構(gòu)的資金有三個(gè)來源,即吸收存款、向其他機(jī)構(gòu)借款和發(fā)行債券。
存款資金的特點(diǎn)之一,是在經(jīng)濟(jì)發(fā)生動(dòng)蕩的時(shí)候,易發(fā)生儲(chǔ)戶爭相提款的現(xiàn)象,從而造成資金來源不穩(wěn)定;
向其他商業(yè)銀行或中央銀行借款所得的資金主要是短期資金,而金融機(jī)構(gòu)往往需要進(jìn)行一些期限較長的投融資,這樣就出現(xiàn)了資金來源和資金運(yùn)用在期限上的矛盾,發(fā)行金融債券比較有效地解決了這個(gè)矛盾。債券在到期之前一般不能提前兌換,只能在市場上轉(zhuǎn)讓,從而保證了所籌集資金的穩(wěn)定性。同時(shí),金融機(jī)構(gòu)發(fā)行債券時(shí)可以靈活規(guī)定期限,比如為了一些長期項(xiàng)目投資,可以發(fā)行期限較長的債券。因此,發(fā)行金融債券可以使金融機(jī)構(gòu)籌措到穩(wěn)定且期限靈活的資金,從而有利于優(yōu)化資產(chǎn)結(jié)構(gòu),擴(kuò)大長期投資業(yè)務(wù)。由于銀行等金融機(jī)構(gòu)在一國經(jīng)濟(jì)中占有較特殊的地位,政府對它們的運(yùn)營又有嚴(yán)格的監(jiān)管,因此,金融債券的資信通常高于其他非金融機(jī)構(gòu)債券,違約風(fēng)險(xiǎn)相對較小,具有較高的安全性。所以,金融債券的利率通常低于。般的企業(yè)債券,但高于風(fēng)險(xiǎn)更小的國債和銀行儲(chǔ)蓄存款利率。
按不同標(biāo)準(zhǔn),金融債券可以劃分為很多種類。最常見的分類有以下兩種:
(1) 根據(jù)利息的支付方式 金融債券可分為附息金融債券和貼現(xiàn)全融債券。如果金融債券上附有多期息票,發(fā)行人定期支付利息,則稱為附息金融債券;如果金融債券是以低于面值的價(jià)格貼現(xiàn)發(fā)行,到期按面值還本付息,利息為發(fā)行價(jià)與面佰的差額,則稱為貼現(xiàn)債券。比如票面金額為1000元,期限為1年的貼現(xiàn)金融債券,發(fā)行價(jià)格為900元,1年到期時(shí)支付給投資者1000元,那么利息收入就是100元,而實(shí)際年利率就是11.11%(即<1 000-900>/900* 100%〕。按照國外通常的做法,貼現(xiàn)金融債券的利息收入要征稅,并且不能在證券交易所上市交易。
(2) 根據(jù)發(fā)行條件 金融債券可分為普通金融債券和累進(jìn)利息金融債券。普通金融債券按面值發(fā)行,到期一次還本付息,期限一般是1年、2年和3年。普通金融債券類似于銀行的定期存款,只是利率高些。累進(jìn)利息金融債券的利率不固定,在不同的時(shí)間段有不同的利率,并且一年比一年高,也就是說,債券的利率隨著債券期限的增加累進(jìn),比如面值1000無、期限為5年的金融債券,第回年利率為9%,第二年利率為10%,第三年為11%,第四年為12%,第五年為13%。投資者可在第一年至第五年之間隨時(shí)去銀行兌付,并獲得規(guī)定的利息。
此外,金融債券也可以像
企業(yè)債券一樣,根據(jù)期限的長短劃分為短期債券、中期債券和長期債券;根據(jù)是否記名劃分為記名債券和不記名債券;根據(jù)擔(dān)保情況劃分為信用債券和擔(dān)保債券;根據(jù)可否提前贖回劃分為可提前贖回債券和不可提前贖回債券;根據(jù)債券票面利率是否變動(dòng)劃分為
固定利率債券、
浮動(dòng)利率債券和
累進(jìn)利率債券;根據(jù)發(fā)行人是否給予投資者選擇權(quán)劃分為附有選擇權(quán)的債券和不附有選擇權(quán)的偵券等。
學(xué)習(xí)資源:
http://www.cnblogs.com/jimmyzhang/archive/2007/10/24/936151.html (花上1-2個(gè)小時(shí)仔細(xì)學(xué)習(xí),然后反復(fù)實(shí)踐,能夠很快上手)
正則表達(dá)式工具:
我首推RegexBuddy了。下面這個(gè)地址里有RegexBuddy3.2.1完整版的下載地址(如果你仔細(xì)瀏覽這個(gè)網(wǎng)站,會(huì)發(fā)現(xiàn)此人是一個(gè)正則表達(dá)式狂熱分子):
http://iregex.org/blog/regexbuddy321.html
1、<script language="javascript">
window.onbeforeunload = function()
{
if(((event.clientX > document.body.clientWidth - 43) && (event.clientY < 23)) || event.altKey) {
window.event.returnValue = '關(guān)閉。';
}
}
</script>
2、<script language="javascript">
window.onbeforeunload = function()
{
var n = window.event.screenX - window.screenLeft;
var b = n > document.documentElement.scrollWidth-20;
if(b && window.event.clientY < 0 || window.event.altKey)
{
alert("是關(guān)閉而非刷新");
window.open(this.location);
//return false;
//window.event.returnValue = ""; }
}
</script>
本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/ajaxchen_615/archive/2009/07/06/4325917.aspx
如果你的頁面對IE7兼容沒有問題,又不想大量修改現(xiàn)有代碼,同時(shí)又能在IE8中正常使用,微軟聲稱,開發(fā)商僅需要在目前兼容IE7的網(wǎng)站上添加一行代碼即可解決問題,此代碼如下:
CODE:
<meta http-equiv="x-ua-compatible" content="ie=7" />
從今天開始學(xué)習(xí).net開發(fā),java開發(fā)工作暫放一放,不過在學(xué)習(xí).net的過程中,會(huì)結(jié)合java對比,在學(xué)習(xí)新知識(shí)的同時(shí)也鞏固和復(fù)習(xí)一下java的知識(shí),在學(xué)習(xí)中提升,在學(xué)習(xí)中成長,加油!
1.對象和屬性
對象是一種復(fù)核數(shù)據(jù)類型,它們將多個(gè)數(shù)據(jù)值幾種在一個(gè)單元中,而且允許使用名字來存取這些值,即對象是一個(gè)無序的屬性集合,這個(gè)屬性都有自己的名字和值,存儲(chǔ)在對象中的以命名的值可以是數(shù)字和字符串這樣的原始值,也可以是對象。
2.對象的創(chuàng)建
對象是由運(yùn)算符new來創(chuàng)建的,在這個(gè)運(yùn)算符之后必須有用于初始化對象的構(gòu)造函數(shù)名。
創(chuàng)建一個(gè)空對象(即沒有屬性的對象)
var o = new Object();
js還支持內(nèi)部構(gòu)造函數(shù),它們以另一種簡潔的方式初始化新創(chuàng)建的對象
var now = new Date();
var new_year = new Date(2009,09,19);
3.屬性的設(shè)置和查詢
4.屬性的枚舉
for/in循環(huán)列出的屬性并沒有特定順序,而且它只能枚舉出所有用戶定義的屬性,但是卻不能枚舉出那些預(yù)定義的屬性或方法,并且它可以
枚舉出被設(shè)為undefined的屬性,但是它不能列出被delete刪除的屬性。
5.未定義的屬性
如果要讀取一個(gè)不存在屬性的值,那么得到的結(jié)果是一個(gè)特殊的js值,undefined
可以使用delete來刪除一個(gè)對象的屬性,注意:刪除一個(gè)屬性并不僅僅是把該屬性設(shè)置為undefined,而是真正從對象中移除了該屬性。
6.構(gòu)造函數(shù)
它由new運(yùn)算符調(diào)用,傳遞給它的是一個(gè)新創(chuàng)建的空對象引用,將該引用作為關(guān)鍵字this的值,而且它還要對新創(chuàng)建的對象進(jìn)行適當(dāng)?shù)某跏蓟?/p>
注意:構(gòu)造函數(shù)如何使用它的參數(shù)來初始化this關(guān)鍵字所引用的對象的屬性,記住,構(gòu)造函數(shù)只是初始化了特定的對象,但并不返回這個(gè)對象。
構(gòu)造函數(shù)通常沒有返回值,他們只是初始化由this值傳遞進(jìn)來的對象,并且什么也不返回..但是,構(gòu)造函數(shù)可以返回一個(gè)對象值,如果這樣做,被返回的對象就成了new表達(dá)式的值了,在這種情況下,
this值所引用的對象就被丟棄了。
7.方法
方法有一個(gè)非常重要的屬性,即在方法主體內(nèi)部,關(guān)鍵字this的值變成了調(diào)用該方法的對象。
方法和函數(shù)的區(qū)別,其實(shí)他們沒有什么技術(shù)上的差別,真正的區(qū)別存在于設(shè)計(jì)和目的上,方法是用來對this對象進(jìn)行操作的,而函數(shù)通常是獨(dú)立的,并不需要使用this對象。
8.原型對象和繼承
js對象都“繼承”原型對象的屬性,每個(gè)對象都有原型對象,原型對象的所有屬性是以它為原型的對象的屬性,也就是說,每個(gè)對象都繼承原型對象的所有屬性,
一個(gè)對象的原型是有創(chuàng)建并初始化該對象的構(gòu)造函數(shù)定義的,js中的所有函數(shù)都有prototype屬性,它引用一個(gè)對象,雖然原型對象初始化時(shí)是空的,但是你在其中定義的任何屬性都會(huì)被構(gòu)造函數(shù)創(chuàng)建
的所有對象繼承。
構(gòu)造函數(shù)定義了對象的類,并初始化了類中狀態(tài)變量的屬性,因?yàn)樵蛯ο蠛蜆?gòu)造函數(shù)關(guān)聯(lián)在一起,所以類的每個(gè)成員都從原型對象繼承了相同的屬性,這說明原型對象是存放方法和其他常量屬性的理
想場所。
繼承是在查詢一個(gè)屬性值時(shí)自動(dòng)發(fā)生的,屬性并非從原型對象賦值到新的對象的,他們只不過看起來像是那些對象的屬性,有兩點(diǎn)重要的含義,一是:使用原型對象可以大量減少每個(gè)對象對內(nèi)存的需求
量,因?yàn)閷ο罂梢岳^承許多屬性;而且即使屬性在對象被創(chuàng)建之后才添加屬性到它的原型對象中,對象也能夠繼承這些屬性。
屬性的繼承只發(fā)生在讀屬性值時(shí),而在寫屬性值時(shí)不會(huì)發(fā)生。
因?yàn)樵蛯ο蟮膶傩员灰粋€(gè)類的所有對象共享,所以通常只用他們來定義類中所有對象的相同的屬性,這使得原型對象適合于方法定義,另外原型對象還適合于具有常量的屬性的定義,
a.原型和內(nèi)部類
不只是用戶定義的類有原型對象,像內(nèi)部類同樣具有原型對象,也可以給他們賦值,
e.g String.prototype.endsWith = function(o){
return (e == this,charAt(this.length-1));
}
9.面向?qū)ο蟮膉s
在面向?qū)ο蟮某绦蛟O(shè)計(jì)中,共有的概念是強(qiáng)類型和支持以類為基礎(chǔ)的繼承機(jī)制,根據(jù)這個(gè)評(píng)判標(biāo)準(zhǔn),就可以證明js不是面向?qū)ο笳Z言。
js對象可以具有大量的屬性,而且還可以動(dòng)態(tài)的將這些屬性添加到對象中,這是對面對象c++和java做不到的,
雖然js沒有類的概念,但是它用構(gòu)造函數(shù)和原型對象模擬了類。
js和以類為基礎(chǔ)的面向?qū)ο笳Z言中,同一個(gè)類可以具有多個(gè)對象,對象是它所屬的那個(gè)類的實(shí)力,所以任何類都可以有多個(gè)實(shí)例,js中的命名延勇了java中的命名約定,即命名類時(shí)以大寫字母開頭,命名對象時(shí)以小寫字母開頭,類幫助我們區(qū)分代碼中的類和對象。
實(shí)例屬性
每個(gè)對象都有它自己單據(jù)的實(shí)力屬性的副本,為了模擬面向?qū)ο蟮某绦蛟O(shè)計(jì)語言,js中的實(shí)例屬性是那些在對象中用構(gòu)造函數(shù)創(chuàng)建的或初始化的屬性。
實(shí)例方法
實(shí)例方法和實(shí)例數(shù)據(jù)非常的相似,實(shí)例方法是由特定對象或?qū)嵗{(diào)用的,實(shí)例方法使用了關(guān)鍵字this來引用他們要操作的對象或?qū)嵗呛蛯?shí)例屬性不同額一點(diǎn)是每個(gè)實(shí)例方法都是由類的所有實(shí)例共享的,在js中,給類定義一個(gè)實(shí)例方法,是通過把構(gòu)造函數(shù)的原型對象中的一個(gè)屬性設(shè)置為函數(shù)值類實(shí)現(xiàn)的,這樣,由那個(gè)構(gòu)造函數(shù)創(chuàng)建的所有對象都會(huì)共享一個(gè)以繼承的對函數(shù)的引用,而且使用上面素?cái)?shù)的方法調(diào)用語法就能夠調(diào)用這個(gè)函數(shù)。
類屬性
類屬性是一個(gè)與類相關(guān)聯(lián)的變量,而不是和類的每個(gè)實(shí)例相關(guān)聯(lián)的變量,每個(gè)類屬性只有一個(gè)副本,它是通過類存取的,可以簡單的定義了構(gòu)造函數(shù)自身的一個(gè)屬性來定義類屬性
類方法
類方法是一個(gè)與類關(guān)聯(lián)在一起的方法,而不是和類的實(shí)例關(guān)聯(lián)在一起的方法,要調(diào)用類方法,就必須使用類本身,而不是使用類的特定實(shí)例。由于類方法不能通過一個(gè)特定對象調(diào)用,所以使用關(guān)鍵字this對它來說沒有意義,和類屬性一樣,類方法是全局性的,
超類和子類
面向?qū)ο笳Z言中有類層次的概念,每個(gè)類都有一個(gè)超類,他們從超類中繼承屬性和方法,類還可以被擴(kuò)展,或者說子類化,這樣其他子類就能繼承它的行為,js中繼承是以原型為基礎(chǔ)的,而不是以類基礎(chǔ)的繼承機(jī)制,但是我們?nèi)耘f能夠總結(jié)出累世的類層次圖,在js中,類Object是最通用的類,其他所有類都是專用化了的版本,或者說的是Object的子類,另一種解釋方法是Object是所有內(nèi)部類的超類,所有類都繼承了Object的基本方法。
舉例說明:
類Complex的對象就繼承了Complex.prototype對象的屬性,而后者又繼承了Object.prototype的屬性,由此可以推出,對象Complex繼承了兩個(gè)對象的屬性,在Complex對象中查詢某個(gè)屬性時(shí),首先查詢的是這個(gè)對象本身,如果在這個(gè)對喜愛那個(gè)中沒有發(fā)現(xiàn)要查詢的屬性,就查詢Complex.prototype對象,最后,如果在那個(gè)對象中還沒有最后按到要查詢的屬性,就查詢Object.prototype對象,注意類層次關(guān)系中的屬性隱藏。參考P153
10.作為關(guān)聯(lián)數(shù)組的對象
運(yùn)算符“.”類存取一個(gè)對象屬性,而數(shù)組更常用的存取書香運(yùn)算賦是[],下面的兩行代碼是等價(jià)的:
obj.property ====== obj["property"],他們的語法區(qū)別是,前者的屬性名是標(biāo)識(shí)符,后者的屬性名卻是一個(gè)字符串,
在c、c++、java和其他類似的強(qiáng)類型語言中,一個(gè)對象的屬性數(shù)是固定,而且必須預(yù)定義這些屬性的名字,由于js是一種弱類型語言,它并沒有采用這一規(guī)則,所以在用js編寫的程序,可以為對象創(chuàng)建任意數(shù)目的屬性,但是當(dāng)你采用“.”運(yùn)算符來存取一個(gè)對象的屬性時(shí),屬性名時(shí)是用標(biāo)識(shí)符表示的,而js程序性中,標(biāo)識(shí)符必須被逐字的輸入,他們不是一種數(shù)據(jù)類型,因此程序不能對他們進(jìn)行操作。
constructor屬性
每個(gè)對象都有constructor屬性,它引用的是用來初始化該對象的構(gòu)造函數(shù)。但是并不是所有的對象都具有自己唯一的constructor屬性,相反,如果這個(gè)屬性是從原型對象繼承來的。
js會(huì)為我們定義的每一個(gè)構(gòu)造函數(shù)都創(chuàng)建一個(gè)原型對象,并且將那個(gè)對象賦給構(gòu)造函數(shù)的prototype屬性。但是之前沒有說明原型對象初始時(shí)是非空的,在原型對象創(chuàng)建之初,它包括一個(gè)constructor屬性, 用來引用構(gòu)造函數(shù),也就是說,如果有一個(gè)函數(shù)f,那么屬性f.prototype.constructor就總是等于f的。
由于構(gòu)造函數(shù)定義了一個(gè)對象的類,所以屬性construtor在確定給定對象的類型時(shí)是一個(gè)功能強(qiáng)大的工具。
并不能保證constructor屬性總是存在的,例如,一個(gè)類的創(chuàng)建者可以用一個(gè)全新的對象來替換構(gòu)造函數(shù)的原型對象,而新對象可能不具有有效的constructor屬性。
toString()方法
toLocaleString()方法
valueOf()方法
js需要將一個(gè)對象轉(zhuǎn)化成字符創(chuàng)之外的原型類型時(shí),就調(diào)用它,這個(gè)函數(shù)返回的是能代表關(guān)鍵字this所引用的對象的值的數(shù)據(jù)。
hasOwnProperty()
如果兌現(xiàn)局部定義了一個(gè)非繼承的屬性,屬性名是由一個(gè)字符串實(shí)際參數(shù)指定的,那么該方法就返回true,否則,它將返回false。
propertyIsEnumerable()
如果對象定義了一個(gè)屬性,屬性名是由一個(gè)字符串實(shí)際參數(shù)指定的,而且該屬性可以用for/in循環(huán)枚舉出來,那么該方法返回true,否則返回false。
注意:該方法只考慮對象直接定義的屬性,而不考慮繼承的屬性,因?yàn)榉祷豧alse可能是因?yàn)槟莻€(gè)屬性是不可枚舉的,也可能是因?yàn)樗m然是可以枚舉的,但卻是個(gè)繼承的屬性。
怎么判斷一個(gè)屬性是可枚舉的?
isPrototypeOf()
如果調(diào)用對象是實(shí)際參數(shù)指定的對象的原型對象,該方法返回true,否則返回false,該方法的用途和對象的constructoe屬性相似。
1.函數(shù)
注意:定義函數(shù)時(shí)可以使用個(gè)數(shù)可變的參數(shù),而且函數(shù)既可以有return語句,也可以沒有return語句;如果函數(shù)不包含return語句,它就只執(zhí)行函數(shù)體中的每條語句,然后返回給調(diào)用者undefined。
使用運(yùn)算符typeof來檢測參數(shù)的數(shù)據(jù)類型,使用if(!param)return;來判斷是否存在該參數(shù),因?yàn)閖s是一種無類型語言,所以你不能給函數(shù)的參數(shù)制定一個(gè)數(shù)據(jù)類型,而且js也不會(huì)檢測傳遞的數(shù)據(jù)是不是那個(gè)函數(shù)所需要的類型,如果參數(shù)很重要時(shí),就使用前面介紹的運(yùn)算符進(jìn)行檢測。
不可變參數(shù)js的處理:如果傳遞的參數(shù)比函數(shù)需要的個(gè)數(shù)多,那么多余的幾個(gè)參數(shù)被忽略掉,如果傳遞的參數(shù)比函數(shù)需要的個(gè)數(shù)少,那么多余的幾個(gè)參數(shù)就會(huì)被賦予undefined,在大多數(shù)情況下,這回使得函數(shù)產(chǎn)生錯(cuò)誤。
2.嵌套函數(shù)
a,函數(shù)定義中可以嵌套其他函數(shù)的定義,但是只能在在頂層全局代碼和頂層函數(shù)代碼中,不能出現(xiàn)在循環(huán)或條件語句中,并且這些限制只應(yīng)用于由function語句聲明的函數(shù),函數(shù)直接量可以出現(xiàn)在任何js表達(dá)式中。
3.Function()構(gòu)造函數(shù)
可以使用Function()構(gòu)造函數(shù)和new運(yùn)算符動(dòng)態(tài)地定義函數(shù), var f = new Function("x","y","return x*y;");它等價(jià)于:function f(x,y){return x*y;}
Function構(gòu)造函數(shù)可以接受任意多個(gè)字符串參數(shù),它的最后一個(gè)參數(shù)是函數(shù)的主體,其中可以包含任何js語句,語句之間用分號(hào)分隔。由于傳遞給構(gòu)造函數(shù)Function()的參數(shù)中沒有一個(gè)用于說明它要?jiǎng)?chuàng)建的函數(shù)名,用Function()構(gòu)造函數(shù)創(chuàng)建的未命名函數(shù)有時(shí)被稱作為“匿名函數(shù)”。
Function()函數(shù)存在的意義:因?yàn)镕unction()構(gòu)造函數(shù)允許我們動(dòng)態(tài)地建立和編譯一個(gè)函數(shù),它不會(huì)將我們限制在function語句預(yù)編譯的函數(shù)體中;另一個(gè)原因是它能將函數(shù)定義為js表達(dá)式的一部分,而不是將其定義為一個(gè)語句;缺點(diǎn)是:這樣做每次調(diào)用一個(gè)函數(shù)時(shí),F(xiàn)unction()構(gòu)造函數(shù)都要對它進(jìn)行編譯,
4.函數(shù)直接量
函數(shù)直接量是一個(gè)表達(dá)式,它可以定義匿名函數(shù)。
function f(x){return x*x;} //function語句
var f = new Function("x","return x*x;"); //Function()構(gòu)造函數(shù)
var f = function(X){return x*x;}; //函數(shù)直接量
雖然函數(shù)直接量創(chuàng)建的是未命名函數(shù),但是它的語法也規(guī)定它可以指定函數(shù)名,這在編寫調(diào)用自身的遞歸函數(shù)時(shí)特別的有用,e.g
var f= function fact(x){if(x<=1)return 1; else return x*fact(x-1);}
總結(jié):function()函數(shù)可以任意的使用,具有通用性,F(xiàn)unction()函數(shù)和函數(shù)直接量具有很多的相似性,他們都是未命名函數(shù)(函數(shù)直接量可以有函數(shù)名,尤其是在子調(diào)用函數(shù)中),函數(shù)直接量有個(gè)重要的有點(diǎn),函數(shù)直接量只被解析和編譯一次,而作為字符串傳遞給Function()構(gòu)造函數(shù)的js代碼則在每次調(diào)用構(gòu)造函數(shù)時(shí)只需要被解析和編譯一次。
函數(shù)最重要的特性就是他們能夠被定義和調(diào)用,但是在js中函數(shù)并不只是一種語法,還可以是數(shù)據(jù),可以把函數(shù)賦給變量、存儲(chǔ)在對象的屬性中或存儲(chǔ)在數(shù)組的元素中,傳遞給函數(shù)。其實(shí)函數(shù)名并沒有什么實(shí)際意義,它只是保存函數(shù)的變量的名字,可以將這個(gè)函數(shù)賦給其他的變量,它仍然以相同的方式起作用,
e.g function square(x){x*x;}
var a = square(4);
var b = square;//這種情況下b引用的函數(shù)和square的作用相同
var c = b(5);
除了賦給全局變量之外,還可以將函數(shù)賦給對象的屬性,這是稱函數(shù)為方法;也可以賦給數(shù)組元素。
e.g
var a = new Object; var a = new Object();
a.square = new Function("x","return x*x";);
y = o.square(16);
e.g
var a = new Array(3);
a[0] = function(x){return x*x;};
a[1] = 20;
a[2] = a[0](a[1]);
除這些之外,如何將函數(shù)作為參數(shù)傳遞給其他函數(shù),
e.g
function add(x,y){return x+y;}
function subtract(x,y){return x-y;}
function multiply(x,y){return x*y;}
function dibide(x,y){return x/y;}
function operate(operator,operand1,operand2){
return operator(operand1,operand2);
}
var i = operate(add,operate(add,2,3),operate(multiply,4,5));
var operators = new Object();
operators["add"] = function(x,y){return x+y;}
operators["multiply"] = function(x,y){return x*y;}
operators["divide"] = function(x,y){return x/y;}
operators["pow"] = Math.pow;
function operate2(op_name,operand1,operand2){
if(operators[op_name] == null)return "unknow operator";
else return operators[op_name](operand1,operand2);
}
var j = operate2('add',"hello",operate2("add","","world"));
var k = operate2('pow',10,2);
5.函數(shù)的作用域,調(diào)用對象
函數(shù)的作用域中除了全局變量、函數(shù)內(nèi)部的局部變量和形式參數(shù)外,函數(shù)還定義了一個(gè)特殊屬性,
arguments,這個(gè)屬性應(yīng)用了另外一個(gè)特殊的對象-----Arguments對象,因?yàn)閍rguments屬性是調(diào)用對象的一個(gè)屬性,所以它的狀態(tài)和局部變量以及函數(shù)的形式參數(shù)是相同的。
所以arguments標(biāo)識(shí)符被看做是保留字,不能將它作為變量名或形式參數(shù)名。
6.Arguments對象
arguments它具有特殊的意義,是調(diào)用對象的一個(gè)特殊屬性,用來引用Arguments對象,Arguments對象就像數(shù)組,可以按照數(shù)字獲取傳遞給函數(shù)的參數(shù)值,但是它并非真正的Array對象。
arguments具有l(wèi)ength屬性,
可以使用arguments來檢測調(diào)用函數(shù)使用了正確數(shù)目的實(shí)際參數(shù),
注意:arguments并非真正的數(shù)組,它是一個(gè)Arguments對象,Arguments對象有一個(gè)非同尋常的特征,當(dāng)函數(shù)具有命名了的參數(shù)時(shí),Arguments對象的數(shù)組元素是存放函數(shù)參數(shù)的局部變量的同義詞。
e.g
function(x){
alert(x); //顯示參數(shù)的初始值
arguments[0] = null;//改變數(shù)組預(yù)算也會(huì)改變x
alert(x); //現(xiàn)在顯示為“null”
除了數(shù)組元素,Arguments對象還定義了callee屬性,用來引用當(dāng)前正在執(zhí)行的函數(shù),這對未命名的函數(shù)調(diào)用自身非常有用。
e.g
function(x){
if(x<-1)return 1;
return x*arguments.callee(x-1);
}
7.函數(shù)的屬性和方法
由于函數(shù)是對象,所以它具有數(shù)據(jù)和方法。
函數(shù)的length屬性
函數(shù)的屬性length和arguments屬性的length不同,arguments數(shù)組的length屬性指定了傳遞給該函數(shù)的實(shí)際參數(shù)數(shù)目,并且arguments屬性的length只在函數(shù)內(nèi)部起作用,而函數(shù)自身的length屬性它是只讀的,返回的是函數(shù)需要的實(shí)際參數(shù)的數(shù)目,并且函數(shù)的屬性length函數(shù)體的內(nèi)部和外部都在是有效的。
函數(shù)的prototype屬性
每個(gè)函數(shù)都有一個(gè)prototype屬性,它引用的是預(yù)定義的原型對象,原型對象在使用new運(yùn)算符把函數(shù)作為構(gòu)造函數(shù)時(shí)起作用。
函數(shù)自定義屬性
有時(shí)候定義全局變量比較亂,可以通過自定義函數(shù)屬性來解決
函數(shù)的apply()和call()方法
他們的第一個(gè)參數(shù)都是要調(diào)用的函數(shù)的對象,在函數(shù)體內(nèi)這一參數(shù)是關(guān)鍵字this的值,call()的剩余參數(shù)是傳遞給要調(diào)用的函數(shù)的值,apply()的剩余參數(shù)是由數(shù)組指定的參數(shù)。
寫出漂亮代碼的七種方法
首先我想說明我本文闡述的是純粹從美學(xué)的角度來寫出代碼,而非技術(shù)、邏輯等。以下為寫出漂亮代碼的七種方法:
1, 盡快結(jié)束 if語句
例如下面這個(gè)JavaScript語句,看起來就很恐怖:
- 1 function findShape(flags, point, attribute, list) {
-
- 2 if(!findShapePoints(flags, point, attribute)) {
-
- 3 if(!doFindShapePoints(flags, point, attribute)) {
-
- 4 if(!findInShape(flags, point, attribute)) {
-
- 5 if(!findFromGuide(flags,point) {
-
- 6 if(list.count() > 0 && flags == 1) {
-
- 7 doSomething();
-
- 8 }
-
- 9 }
-
- 10 }
-
- 11 }
-
- 12 }
-
- 13 }
1 function findShape(flags, point, attribute, list) {
2 if(!findShapePoints(flags, point, attribute)) {
3 if(!doFindShapePoints(flags, point, attribute)) {
4 if(!findInShape(flags, point, attribute)) {
5 if(!findFromGuide(flags,point) {
6 if(list.count() > 0 && flags == 1) {
7 doSomething();
8 }
9 }
10 }
11 }
12 }
13 }
但如果這么寫就好看得多:
- 1 function findShape(flags, point, attribute, list) {
-
- 2 if(findShapePoints(flags, point, attribute)) {
-
- 3 return;
-
- 4 }
-
- 5
-
- 6 if(doFindShapePoints(flags, point, attribute)) {
-
- 7 return;
-
- 8 }
-
- 9
-
- 10 if(findInShape(flags, point, attribute)) {
-
- 11 return;
-
- 12 }
-
- 13
-
- 14 if(findFromGuide(flags,point) {
-
- 15 return;
-
- 16 }
-
- 17
-
- 18 if (!(list.count() > 0 && flags == 1)) {
-
- 19 return;
-
- 20 }
-
- 21
-
- 22 doSomething();
-
- 23
-
- 24 }
1 function findShape(flags, point, attribute, list) {
2 if(findShapePoints(flags, point, attribute)) {
3 return;
4 }
5
6 if(doFindShapePoints(flags, point, attribute)) {
7 return;
8 }
9
10 if(findInShape(flags, point, attribute)) {
11 return;
12 }
13
14 if(findFromGuide(flags,point) {
15 return;
16 }
17
18 if (!(list.count() > 0 && flags == 1)) {
19 return;
20 }
21
22 doSomething();
23
24 }
你可能會(huì)很不喜歡第二種的表述方式,但反映出了迅速返回if值的思想,也可以理解為:避免不必要的else陳述。
2, 如果只是簡單的布爾運(yùn)算(邏輯運(yùn)算),不要使用if語句
例如:
- 1 function isStringEmpty(str){
-
- 2 if(str === "") {
-
- 3 return true;
-
- 4 }
-
- 5 else {
-
- 6 return false;
-
- 7 }
-
- 8 }
1 function isStringEmpty(str){
2 if(str === "") {
3 return true;
4 }
5 else {
6 return false;
7 }
8 }
可以寫為:
- 1 function isStringEmpty(str){
-
- 2 return (str === "");
-
- 3 }
1 function isStringEmpty(str){
2 return (str === "");
3 }
3, 使用空白,這是免費(fèi)的
例如:
1
- function getSomeAngle() {
-
- 2
-
- 3 radAngle1 = Math.atan(slope(center, point1));
-
- 4 radAngle2 = Math.atan(slope(center, point2));
-
- 5 firstAngle = getStartAngle(radAngle1, point1, center);
-
- 6 secondAngle = getStartAngle(radAngle2, point2, center);
-
- 7 radAngle1 = degreesToRadians(firstAngle);
-
- 8 radAngle2 = degreesToRadians(secondAngle);
-
- 9 baseRadius = distance(point, center);
-
- 10 radius = baseRadius + (lines * y);
-
- 11 p1["x"] = roundValue(radius * Math.cos(radAngle1) + center["x"]);
-
- 12 p1["y"] = roundValue(radius * Math.sin(radAngle1) + center["y"]);
-
- 13 pt2["x"] = roundValue(radius * Math.cos(radAngle2) + center["y"]);
-
- 14 pt2["y"] = roundValue(radius * Math.sin(radAngle2) + center["y");
-
- 15
-
- 16 }
function getSomeAngle() {
2 // Some code here then
3 radAngle1 = Math.atan(slope(center, point1));
4 radAngle2 = Math.atan(slope(center, point2));
5 firstAngle = getStartAngle(radAngle1, point1, center);
6 secondAngle = getStartAngle(radAngle2, point2, center);
7 radAngle1 = degreesToRadians(firstAngle);
8 radAngle2 = degreesToRadians(secondAngle);
9 baseRadius = distance(point, center);
10 radius = baseRadius + (lines * y);
11 p1["x"] = roundValue(radius * Math.cos(radAngle1) + center["x"]);
12 p1["y"] = roundValue(radius * Math.sin(radAngle1) + center["y"]);
13 pt2["x"] = roundValue(radius * Math.cos(radAngle2) + center["y"]);
14 pt2["y"] = roundValue(radius * Math.sin(radAngle2) + center["y");
15 // Now some more code
16 }
很多開發(fā)者不愿意使用空白,就好像這要收費(fèi)一樣。我在此并非刻意地添加空白,粗魯?shù)卮驍啻a的連貫性。在實(shí)際編寫代碼的過程中,會(huì)很容易地發(fā)現(xiàn)在什么地方加入空白,這不但美觀而且讓讀者易懂,如下:
- 1 function getSomeAngle() {
-
- 2
-
- 3 radAngle1 = Math.atan(slope(center, point1));
-
- 4 radAngle2 = Math.atan(slope(center, point2));
-
- 5
-
- 6 firstAngle = getStartAngle(radAngle1, point1, center);
-
- 7 secondAngle = getStartAngle(radAngle2, point2, center);
-
- 8
-
- 9 radAngle1 = degreesToRadians(firstAngle);
-
- 10 radAngle2 = degreesToRadians(secondAngle);
-
- 11
-
- 12 baseRadius = distance(point, center);
-
- 13 radius = baseRadius + (lines * y);
-
- 14
-
- 15 p1["x"] = roundValue(radius * Math.cos(radAngle1) + center["x"]);
-
- 16 p1["y"] = roundValue(radius * Math.sin(radAngle1) + center["y"]);
-
- 17
-
- 18 pt2["x"] = roundValue(radius * Math.cos(radAngle2) + center["y"]);
-
- 19 pt2["y"] = roundValue(radius * Math.sin(radAngle2) + center["y");
-
- 20
-
- 21 }
-
-
-
- 4, 不要使用無謂的注釋
-
- 無謂的注釋讓人費(fèi)神,這實(shí)在很討厭。不要標(biāo)出很明顯的注釋。在以下的例子中,每個(gè)人都知道代碼表達(dá)的是“students id”,因而沒必要標(biāo)出。
-
- 1 function existsStudent(id, list) {
-
- 2 for(i = 0; i < list.length; i++) {
-
- 3 student = list[i];
-
- 4
-
- 5
-
- 6 thisId = student.getId();
-
- 7
-
- 8 if(thisId === id) {
-
- 9 return true;
-
- 10 }
-
- 11 }
-
- 12 return false;
-
- 13 }
1 function getSomeAngle() {
2 // Some code here then
3 radAngle1 = Math.atan(slope(center, point1));
4 radAngle2 = Math.atan(slope(center, point2));
5
6 firstAngle = getStartAngle(radAngle1, point1, center);
7 secondAngle = getStartAngle(radAngle2, point2, center);
8
9 radAngle1 = degreesToRadians(firstAngle);
10 radAngle2 = degreesToRadians(secondAngle);
11
12 baseRadius = distance(point, center);
13 radius = baseRadius + (lines * y);
14
15 p1["x"] = roundValue(radius * Math.cos(radAngle1) + center["x"]);
16 p1["y"] = roundValue(radius * Math.sin(radAngle1) + center["y"]);
17
18 pt2["x"] = roundValue(radius * Math.cos(radAngle2) + center["y"]);
19 pt2["y"] = roundValue(radius * Math.sin(radAngle2) + center["y");
20 // Now some more code
21 }
4, 不要使用無謂的注釋
無謂的注釋讓人費(fèi)神,這實(shí)在很討厭。不要標(biāo)出很明顯的注釋。在以下的例子中,每個(gè)人都知道代碼表達(dá)的是“students id”,因而沒必要標(biāo)出。
1 function existsStudent(id, list) {
2 for(i = 0; i < list.length; i++) {
3 student = list[i];
4
5 // Get the student's id
6 thisId = student.getId();
7
8 if(thisId === id) {
9 return true;
10 }
11 }
12 return false;
13 }
5, 不要在源文件中留下已經(jīng)刪除的代碼,哪怕你標(biāo)注了
如果你使用了版本控制,那么你就可以輕松地找回前一個(gè)版本的代碼。如果別人大費(fèi)周折地讀了你的代碼,卻發(fā)現(xiàn)是要?jiǎng)h除的代碼,這實(shí)在太恨人了。
//function thisReallyHandyFunction() {
// someMagic();
// someMoreMagic();
// magicNumber = evenMoreMagic();
// return magicNumber;
//}
6,不要有太長的代碼
看太長的代碼實(shí)在太費(fèi)勁,尤其是代碼本身的功能又很小。如下:
- 1 public static EnumMap<Category, IntPair> getGroupCategoryDistribution(EnumMap<Category, Integer> sizes, int groups) {
-
- 2 EnumMap<Category, IntPair> categoryGroupCounts = new EnumMap<Category,IntPair>(Category.class);
-
- 3
-
- 4 for(Category cat : Category.values()) {
-
- 5 categoryGroupCounts.put(cat, getCategoryDistribution(sizes.get(cat), groups));
-
- 6 }
1 public static EnumMap<Category, IntPair> getGroupCategoryDistribution(EnumMap<Category, Integer> sizes, int groups) {
2 EnumMap<Category, IntPair> categoryGroupCounts = new EnumMap<Category,IntPair>(Category.class);
3
4 for(Category cat : Category.values()) {
5 categoryGroupCounts.put(cat, getCategoryDistribution(sizes.get(cat), groups));
6 }
#
我并不是說非要堅(jiān)持70個(gè)字符以內(nèi),但是一個(gè)比較理想的長度是控制在120個(gè)字符內(nèi)。如果你把代碼發(fā)布在互聯(lián)網(wǎng)上,用戶讀起來就很困難。
7,不要在一個(gè)功能(或者函數(shù)內(nèi))有太多代碼行
我的一個(gè)老同事曾經(jīng)說Visual C++很臭,因?yàn)樗辉试S你在一個(gè)函數(shù)內(nèi)擁有超過10,000行代碼。我記不清代碼行數(shù)的上限,不知道他說的是否正確,但我很不贊成他的觀點(diǎn)。如果一個(gè)函數(shù)超過了50行,看起來有多費(fèi)勁你知道么,還有沒完沒了的if循環(huán),而且你還的滾動(dòng)鼠標(biāo)前后對照這段代碼。對我而言,超過35行的代碼理解起來就很困難了。我的建議是超過這個(gè)數(shù)字就把一個(gè)函數(shù)代碼分割成兩個(gè)。
本篇文章為在工作中使用JAVA反射的經(jīng)驗(yàn)總結(jié),也可以說是一些小技巧,以后學(xué)會(huì)新的小技巧,會(huì)不斷更新。
在開始之前,我先定義一個(gè)測試類Student,代碼如下:
- package chb.test.reflect;
-
- public class Student {
- private int age;
- private String name;
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
-
- public static void hi(int age,String name){
- System.out.println("大家好,我叫"+name+",今年"+age+"歲");
- }
- }<PRE></PRE>
package chb.test.reflect;
public class Student {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void hi(int age,String name){
System.out.println("大家好,我叫"+name+",今年"+age+"歲");
}
}
一、JAVA反射的常規(guī)使用步驟
反射調(diào)用一般分為3個(gè)步驟:
代碼示例:
- Class cls = Class.forName("chb.test.reflect.Student");
- Method m = cls.getDeclaredMethod("hi",new Class[]{int.class,String.class});
- m.invoke(cls.newInstance(),20,"chb");<PRE></PRE>
Class cls = Class.forName("chb.test.reflect.Student");
Method m = cls.getDeclaredMethod("hi",new Class[]{int.class,String.class});
m.invoke(cls.newInstance(),20,"chb");
二、方法調(diào)用中的參數(shù)類型
在方法調(diào)用中,參數(shù)類型必須正確,這里需要注意的是不能使用包裝類替換基本類型,比如不能使用Integer.class代替int.class。
如我要調(diào)用Student的setAge方法,下面的調(diào)用是正確的:
- Class cls = Class.forName("chb.test.reflect.Student");
- Method setMethod = cls.getDeclaredMethod("setAge",int.class);
- setMethod.invoke(cls.newInstance(), 15);<PRE></PRE>
Class cls = Class.forName("chb.test.reflect.Student");
Method setMethod = cls.getDeclaredMethod("setAge",int.class);
setMethod.invoke(cls.newInstance(), 15);
而如果我們用Integer.class替代int.class就會(huì)出錯(cuò),如:
- Class cls = Class.forName("chb.test.reflect.Student");
- Method setMethod = cls.getDeclaredMethod("setAge",Integer.class);
- setMethod.invoke(cls.newInstance(), 15);<PRE></PRE>
Class cls = Class.forName("chb.test.reflect.Student");
Method setMethod = cls.getDeclaredMethod("setAge",Integer.class);
setMethod.invoke(cls.newInstance(), 15);
jvm會(huì)報(bào)出如下異常:
- java.lang.NoSuchMethodException: chb.test.reflect.Student.setAge(java.lang.Integer)
- at java.lang.Class.getDeclaredMethod(Unknown Source)
- at chb.test.reflect.TestClass.testReflect(TestClass.java:23)<PRE></PRE>
java.lang.NoSuchMethodException: chb.test.reflect.Student.setAge(java.lang.Integer)
at java.lang.Class.getDeclaredMethod(Unknown Source)
at chb.test.reflect.TestClass.testReflect(TestClass.java:23)
三、static方法的反射調(diào)用
static方法調(diào)用時(shí),不必得到對象示例,如下:
- Class cls = Class.forName("chb.test.reflect.Student");
- Method staticMethod = cls.getDeclaredMethod("hi",int.class,String.class);
- staticMethod.invoke(cls,20,"chb");
-
Class cls = Class.forName("chb.test.reflect.Student");
Method staticMethod = cls.getDeclaredMethod("hi",int.class,String.class);
staticMethod.invoke(cls,20,"chb");//這里不需要newInstance
//staticMethod.invoke(cls.newInstance(),20,"chb");
四、private的成員變量賦值
如果直接通過反射給類的private成員變量賦值,是不允許的,這時(shí)我們可以通過setAccessible方法解決。代碼示例:
- Class cls = Class.forName("chb.test.reflect.Student");
- Object student = cls.newInstance();
- Field field = cls.getDeclaredField("age");
- field.set(student, 10);
- System.out.println(field.get(student));<PRE></PRE>
Class cls = Class.forName("chb.test.reflect.Student");
Object student = cls.newInstance();//得到一個(gè)實(shí)例
Field field = cls.getDeclaredField("age");
field.set(student, 10);
System.out.println(field.get(student));
運(yùn)行如上代碼,系統(tǒng)會(huì)報(bào)出如下異常:
- java.lang.IllegalAccessException: Class chb.test.reflect.TestClass can not access a member of class chb.test.reflect.Student with modifiers "private"
- at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
- at java.lang.reflect.Field.doSecurityCheck(Unknown Source)
- at java.lang.reflect.Field.getFieldAccessor(Unknown Source)
- at java.lang.reflect.Field.set(Unknown Source)
- at chb.test.reflect.TestClass.testReflect(TestClass.java:20)<PRE></PRE>
java.lang.IllegalAccessException: Class chb.test.reflect.TestClass can not access a member of class chb.test.reflect.Student with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
at java.lang.reflect.Field.doSecurityCheck(Unknown Source)
at java.lang.reflect.Field.getFieldAccessor(Unknown Source)
at java.lang.reflect.Field.set(Unknown Source)
at chb.test.reflect.TestClass.testReflect(TestClass.java:20)
解決方法:
- Class cls = Class.forName("chb.test.reflect.Student");
- Object student = cls.newInstance();
- Field field = cls.getDeclaredField("age");
- field.setAccessible(true);
- field.set(student, 10);
- System.out.println(field.get(student));<PRE></PRE>
Class cls = Class.forName("chb.test.reflect.Student");
Object student = cls.newInstance();
Field field = cls.getDeclaredField("age");
field.setAccessible(true);//設(shè)置允許訪問
field.set(student, 10);
System.out.println(field.get(student));
其實(shí),在某些場合下(類中有g(shù)et,set方法),可以先反射調(diào)用set方法,再反射調(diào)用get方法達(dá)到如上效果,代碼示例:
- Class cls = Class.forName("chb.test.reflect.Student");
- Object student = cls.newInstance();
-
- Method setMethod = cls.getDeclaredMethod("setAge",Integer.class);
- setMethod.invoke(student, 15);
-
- Method getMethod = cls.getDeclaredMethod("getAge");
- System.out.println(getMethod.invoke(student));
|
Reflection 是 Java 程序開發(fā)語言的特征之一,它允許運(yùn)行中的 Java 程序?qū)ψ陨磉M(jìn)行檢查,或者說“自審”,并能直接操作程序的內(nèi)部屬性。例如,使用它能獲得 Java 類中各成員的名稱并顯示出來。JavaBean 是 reflection 的實(shí)際應(yīng)用之一,它能讓一些工具可視化的操作軟件組件。這些工具通過 reflection 動(dòng)態(tài)的載入并取得 Java 組件(類) 的屬性。
1. 一個(gè)簡單的例子
考慮下面這個(gè)簡單的例子,讓我們看看 reflection 是如何工作的。
import java.lang.reflect.*;
public class DumpMethods {
public static void main(String args[]) {
try {
Class c = Class.forName(args[0]);
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
System.out.println(m[i].toString());
} catch (Throwable e) {
System.err.println(e);
}
}
}
按如下語句執(zhí)行:
java DumpMethods java.util.Stack
它的結(jié)果輸出為:
public java.lang.Object java.util.Stack.push(java.lang.Object)
public synchronized java.lang.Object java.util.Stack.pop()
public synchronized java.lang.Object java.util.Stack.peek()
public boolean java.util.Stack.empty()
public synchronized int java.util.Stack.search(java.lang.Object)
這樣就列出了java.util.Stack 類的各方法名以及它們的限制符和返回類型。
這個(gè)程序使用 Class.forName 載入指定的類,然后調(diào)用 getDeclaredMethods 來獲取這個(gè)類中定義了的方法列表。java.lang.reflect.Methods 是用來描述某個(gè)類中單個(gè)方法的一個(gè)類。還有就是getDeclaredMethod(para1,para2)來獲取這個(gè)類中的具體某一個(gè)方法,其中para1是一個(gè)String類型,具體代表的是方法名,para2是個(gè)一個(gè)Class類型的數(shù)組,其中定義個(gè)方法的具體參數(shù)類型。
例如:
- Class cls = Class.forName("chb.test.reflect.Student");
- Method m = cls.getDeclaredMethod("方法名",new Class[]{int.class,String.class});
- m.invoke(cls.newInstance(),20,"chb");
總結(jié):
//使用反射類調(diào)用某個(gè)類中的方法
Class c = Class.forName("com.inspur.reflect.MethodTest");
Method n = c.getDeclaredMethod("show", new Class[]{String.class,int.class});
n.invoke(c.newInstance(), "guoxzh",20);
a.使用Class.forName("類名")來獲取類
b.其次使用getDeclaredMethods()方法獲取該類所有的方法,也可以使用getDeclaredMethod("方法名",new Class[]{int.class,String.class})方法類獲取具體的某一個(gè)方法
c.接著可以使用invoke(c.newInstance,param....)來調(diào)用具體的方法。
2.詳細(xì)介紹開始使用 Reflection
用于 reflection 的類,如 Method,可以在 java.lang.relfect 包中找到。使用這些類的時(shí)候必須要遵循三個(gè)步驟:第一步是獲得你想操作的類的 java.lang.Class 對象。在運(yùn)行中的 Java 程序中,用 java.lang.Class 類來描述類和接口等。
下面就是獲得一個(gè) Class 對象的方法之一:
Class c = Class.forName("java.lang.String");
這條語句得到一個(gè) String 類的類對象。還有另一種方法,如下面的語句:
Class c = int.class;
或者
Class c = Integer.TYPE;
它們可獲得基本類型的類信息。其中后一種方法中訪問的是基本類型的封裝類 (如 Integer) 中預(yù)先定義好的 TYPE 字段。
第二步是調(diào)用諸如 getDeclaredMethods 的方法,以取得該類中定義的所有方法的列表。
一旦取得這個(gè)信息,就可以進(jìn)行第三步了——使用 reflection API 來操作這些信息,如下面這段代碼:
Class c = Class.forName("java.lang.String");
Method m[] = c.getDeclaredMethods();
System.out.println(m[0].toString());
它將以文本方式打印出 String 中定義的第一個(gè)方法的原型。
在下面的例子中,這三個(gè)步驟將為使用 reflection 處理特殊應(yīng)用程序提供例證。
模擬 instanceof 操作符
得到類信息之后,通常下一個(gè)步驟就是解決關(guān)于 Class 對象的一些基本的問題。例如,Class.isInstance 方法可以用于模擬 instanceof 操作符:
class A {
}
public class instance1 {
public static void main(String args[]) {
try {
Class cls = Class.forName("A");
boolean b1 = cls.isInstance(new Integer(37)); //判斷Integer(37)該對象是否是A類的對象
System.out.println(b1);
boolean b2 = cls.isInstance(new A());
System.out.println(b2);
} catch (Throwable e) {
System.err.println(e);
}
}
}
在這個(gè)例子中創(chuàng)建了一個(gè) A 類的 Class 對象,然后檢查一些對象是否是 A 的實(shí)例。Integer(37) 不是,但 new A() 是。
3.找出類的方法
找出一個(gè)類中定義了些什么方法,這是一個(gè)非常有價(jià)值也非常基礎(chǔ)的 reflection 用法。下面的代碼就實(shí)現(xiàn)了這一用法:
package com.inspur.reflect;
import java.lang.reflect.Method;
public class Methodtest1 {
private int abc(Object p,int x) throws NullPointerException{
if(p==null)throw new NullPointerException();
return x;
}
public static void main(String[] args) {
try{
Class cls = Class.forName("com.inspur.reflect.Methodtest1");
Method methodlist[]= cls.getDeclaredMethods();
for(int i = 0;i<methodlist.length;i++){
Method m = methodlist[i];
System.out.println("name=="+m.getName());//得到方法的名稱
System.out.println("decl class=="+m.getDeclaringClass());//得到定義的類名
Class prev[] = m.getParameterTypes(); //取m方法中的所有參數(shù)
//遍歷所有的參數(shù)
for(int j = 0; j<prev.length;j++){
System.out.println("param["+j+"]=="+prev[j]);
}
Class exec[] = m.getExceptionTypes(); //得到所有的異常
//遍歷所有的異常
for(int k=0;k<exec.length;k++){
System.out.println("execption["+k+"]=="+exec[k]);
}
Class ret = m.getReturnType(); //得到每個(gè)方法的返回值
System.out.println("return leixing=="+ret.toString());
}
}catch(Throwable e){
System.err.println(e.getMessage());
}
}
}
這個(gè)程序首先取得 method1 類的描述,然后調(diào)用 getDeclaredMethods 來獲取一系列的 Method 對象,它們分別描述了定義在類中的每一個(gè)方法,包括 public 方法、protected 方法、package 方法和 private 方法等。
如果你在程序中使用 getMethods 來代替 getDeclaredMethods,你還能獲得繼承來的各個(gè)方法的信息。同時(shí)你也可以使用Modifier.toString(m.getModifiers())來獲取方法的限制屬性。
取得了 Method 對象列表之后,要顯示這些方法的參數(shù)類型、異常類型和返回值類型等就不難了。這些類型是基本類型還是類類型,都可以由描述類的對象按順序給出。
輸出的結(jié)果如下:
name==main
decl class==class com.inspur.reflect.Methodtest1
param[0]==class [Ljava.lang.String;
return leixing==void
name==abc
decl class==class com.inspur.reflect.Methodtest1
param[0]==class java.lang.Object
param[1]==int
execption[0]==class java.lang.NullPointerException
return leixing==int 4.獲取構(gòu)造器信息
獲取類構(gòu)造器的用法與上述獲取方法的用法類似,如:
import java.lang.reflect.*;
public class constructor1 {
public constructor1() {
}
protected constructor1(int i, double d) {
}
public static void main(String args[]) {
try {
Class cls = Class.forName("constructor1");
Constructor ctorlist[] = cls.getDeclaredConstructors();
for (int i = 0; i < ctorlist.length; i++) {
Constructor ct = ctorlist[i];
System.out.println("name = " + ct.getName());
System.out.println("decl class = " + ct.getDeclaringClass());
Class pvec[] = ct.getParameterTypes();
for (int j = 0; j < pvec.length; j++)
System.out.println("param #" + j + " " + pvec[j]);
Class evec[] = ct.getExceptionTypes();
for (int j = 0; j < evec.length; j++)
System.out.println("exc #" + j + " " + evec[j]);
System.out.println("-----");
}
} catch (Throwable e) {
System.err.println(e);
}
}
}
這個(gè)例子中沒能獲得返回類型的相關(guān)信息,那是因?yàn)闃?gòu)造器沒有返回類型。
這個(gè)程序運(yùn)行的結(jié)果是:
name = constructor1
decl class = class constructor1
-----
name = constructor1
decl class = class constructor1
param #0 int
param #1 double
-----
5.獲取類的字段(域)
找出一個(gè)類中定義了哪些數(shù)據(jù)字段也是可能的,下面的代碼就在干這個(gè)事情:
import java.lang.reflect.*;
public class field1 {
private double d;
public static final int i = 37;
String s = "testing";
public static void main(String args[]) {
try {
Class cls = Class.forName("field1");
Field fieldlist[] = cls.getDeclaredFields();
for (int i = 0; i < fieldlist.length; i++) {
Field fld = fieldlist[i];
System.out.println("name = " + fld.getName());
System.out.println("decl class = " + fld.getDeclaringClass());
System.out.println("type = " + fld.getType());
int mod = fld.getModifiers();
System.out.println("modifiers = " + Modifier.toString(mod));
System.out.println("-----");
}
} catch (Throwable e) {
System.err.println(e);
}
}
}
這個(gè)例子和前面那個(gè)例子非常相似。例中使用了一個(gè)新東西 Modifier,它也是一個(gè) reflection 類,用來描述字段成員的修飾語,如“private int”。這些修飾語自身由整數(shù)描述,而且使用 Modifier.toString 來返回以“官方”順序排列的字符串描述 (如“static”在“final”之前)。這個(gè)程序的輸出是:
name = d
decl class = class field1
type = double
modifiers = private
-----
name = i
decl class = class field1
type = int
modifiers = public static final
-----
name = s
decl class = class field1
type = class java.lang.String
modifiers =
-----
和獲取方法的情況一下,獲取字段的時(shí)候也可以只取得在當(dāng)前類中申明了的字段信息 (getDeclaredFields),或者也可以取得父類中定義的字段 (getFields) 。
6.根據(jù)方法的名稱來執(zhí)行方法
文本到這里,所舉的例子無一例外都與如何獲取類的信息有關(guān)。我們也可以用 reflection 來做一些其它的事情,比如執(zhí)行一個(gè)指定了名稱的方法。下面的示例演示了這一操作:
import java.lang.reflect.*;
public class method2 {
public int add(int a, int b) {
return a + b;
}
public static void main(String args[]) {
try {
Class cls = Class.forName("method2");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Method meth = cls.getMethod("add", partypes);
method2 methobj = new method2();
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj = meth.invoke(methobj, arglist);
Integer retval = (Integer) retobj;
System.out.println(retval.intValue());
} catch (Throwable e) {
System.err.println(e);
}
}
}
假如一個(gè)程序在執(zhí)行的某處的時(shí)候才知道需要執(zhí)行某個(gè)方法,這個(gè)方法的名稱是在程序的運(yùn)行過程中指定的 (例如,JavaBean 開發(fā)環(huán)境中就會(huì)做這樣的事),那么上面的程序演示了如何做到。
上例中,getMethod 用于查找一個(gè)具有兩個(gè)整型參數(shù)且名為 add 的方法。找到該方法并創(chuàng)建了相應(yīng)的 Method 對象之后,在正確的對象實(shí)例中執(zhí)行它。執(zhí)行該方法的時(shí)候,需要提供一個(gè)參數(shù)列表,這在上例中是分別包裝了整數(shù) 37 和 47 的兩個(gè) Integer 對象。執(zhí)行方法的返回的同樣是一個(gè) Integer 對象,它封裝了返回值 84。
7.創(chuàng)建新的對象
對于構(gòu)造器,則不能像執(zhí)行方法那樣進(jìn)行,因?yàn)閳?zhí)行一個(gè)構(gòu)造器就意味著創(chuàng)建了一個(gè)新的對象 (準(zhǔn)確的說,創(chuàng)建一個(gè)對象的過程包括分配內(nèi)存和構(gòu)造對象)。所以,與上例最相似的例子如下:
import java.lang.reflect.*;
public class constructor2 {
public constructor2() {
}
public constructor2(int a, int b) {
System.out.println("a = " + a + " b = " + b);
}
public static void main(String args[]) {
try {
Class cls = Class.forName("constructor2");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Constructor ct = cls.getConstructor(partypes);
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj = ct.newInstance(arglist);
} catch (Throwable e) {
System.err.println(e);
}
}
}
根據(jù)指定的參數(shù)類型找到相應(yīng)的構(gòu)造函數(shù)并執(zhí)行它,以創(chuàng)建一個(gè)新的對象實(shí)例。使用這種方法可以在程序運(yùn)行時(shí)動(dòng)態(tài)地創(chuàng)建對象,而不是在編譯的時(shí)候創(chuàng)建對象,這一點(diǎn)非常有價(jià)值。
(這里如果使用無參構(gòu)造器創(chuàng)建對象的話,這可以直接使用Class.forName("...").newInstance();來創(chuàng)建對象)
8.改變字段(域)的值
reflection 的還有一個(gè)用處就是改變對象數(shù)據(jù)字段的值。reflection 可以從正在運(yùn)行的程序中根據(jù)名稱找到對象的字段并改變它,下面的例子可以說明這一點(diǎn):
import java.lang.reflect.*;
public class field2 {
public double d;
public static void main(String args[]) {
try {
Class cls = Class.forName("field2");
Field fld = cls.getField("d");
field2 f2obj = new field2();
System.out.println("d = " + f2obj.d);
fld.setDouble(f2obj, 12.34);
System.out.println("d = " + f2obj.d);
} catch (Throwable e) {
System.err.println(e);
}
}
}
這個(gè)例子中,字段 d 的值被變?yōu)榱?12.34。
9.使用數(shù)組
本文介紹的 reflection 的最后一種用法是創(chuàng)建的操作數(shù)組。數(shù)組在 Java 語言中是一種特殊的類類型,一個(gè)數(shù)組的引用可以賦給 Object 引用。觀察下面的例子看看數(shù)組是怎么工作的:
import java.lang.reflect.*;
public class array1 {
public static void main(String args[]) {
try {
Class cls = Class.forName("java.lang.String");
Object arr = Array.newInstance(cls, 10);
Array.set(arr, 5, "this is a test");
String s = (String) Array.get(arr, 5);
System.out.println(s);
} catch (Throwable e) {
System.err.println(e);
}
}
}
例中創(chuàng)建了 10 個(gè)單位長度的 String 數(shù)組,為第 5 個(gè)位置的字符串賦了值,最后將這個(gè)字符串從數(shù)組中取得并打印了出來。
下面這段代碼提供了一個(gè)更復(fù)雜的例子:
import java.lang.reflect.*;
public class array2 {
public static void main(String args[]) {
int dims[] = new int[]{5, 10, 15};
Object arr = Array.newInstance(Integer.TYPE, dims);
Object arrobj = Array.get(arr, 3);
Class cls = arrobj.getClass().getComponentType();
System.out.println(cls);
arrobj = Array.get(arrobj, 5);
Array.setInt(arrobj, 10, 37);
int arrcast[][][] = (int[][][]) arr;
System.out.println(arrcast[3][5][10]);
}
}
例中創(chuàng)建了一個(gè) 5 x 10 x 15 的整型數(shù)組,并為處于 [3][5][10] 的元素賦了值為 37。注意,多維數(shù)組實(shí)際上就是數(shù)組的數(shù)組,例如,第一個(gè) Array.get 之后,arrobj 是一個(gè) 10 x 15 的數(shù)組。進(jìn)而取得其中的一個(gè)元素,即長度為 15 的數(shù)組,并使用 Array.setInt 為它的第 10 個(gè)元素賦值。
注意創(chuàng)建數(shù)組時(shí)的類型是動(dòng)態(tài)的,在編譯時(shí)并不知道其類型。
摘要: 轉(zhuǎn)自其他博客《收藏》
(1) 選擇最有效率的表名順序(只在基于規(guī)則的優(yōu)化器中有效):
ORACLE的解析器按照從右到左的順序處理FROM子句中的表名,F(xiàn)ROM子句中寫在最后的表(基礎(chǔ)表 driving table)將被最先處理,在FROM子句中包含多個(gè)表的情況下,你必須選擇記錄條數(shù)最少的表作為基礎(chǔ)表。如果有3個(gè)以上的表連接查詢,...
閱讀全文
1,使用Spring 的 ActionSupport
2,使用Spring 的 DelegatingRequestProcessor 類。
3,全權(quán)委托。
無論用那種方法來整合第一步就是要為struts來裝載spring的應(yīng)用環(huán)境。 就是在 struts 中加入一個(gè)插件。
struts-config.xml中
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml"/>
</plug-in>
|
spring 的配置文件被作為參數(shù)配置進(jìn)來。這樣可以省略對web.xml 文件中的配置。確保你的applicationContext.xml 在WEB-INF目錄下面
1、使用Spring的ActionSupport .
Spring 的ActionSupport 繼承至org.apache.struts.action.Action
ActionSupport的子類可以或得 WebApplicationContext類型的全局變量。通過getWebApplicationContext()可以獲得這個(gè)變量。
這是一個(gè) servlet 的代碼:
public class LoginAction extends org.springframework.web.struts.ActionSupport {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
LoginForm loginForm = (LoginForm) form;// TODO Auto-generated method stub
//獲得 WebApplicationContext 對象
WebApplicationContext ctx = this.getWebApplicationContext();
LoginDao dao = (LoginDao) ctx.getBean("loginDao");
User u = new User();
u.setName(loginForm.getName());
u.setPwd(loginForm.getPwd());
if(dao.checkLogin(u)){
return mapping.findForward("success");
}else{
return mapping.findForward("error");
}
}
}
applicationContext.xml 中的配置
<beans>
<bean id="loginDao" class="com.cao.dao.LoginDao"/>
</beans>
|
這中配置方式同直接在web.xml文件配置差別不大。
注意:Action繼承自 org.springframework.web.struts.ActionSupport 使得struts和spring耦合在一起。
但實(shí)現(xiàn)了表示層和業(yè)務(wù)邏輯層的解耦(LoginDao dao = (LoginDao) ctx.getBean("loginDao"))。
2、使用Spring 的 DelegatingRequestProcessor 類
DelegatingRequestProcessor 繼承自 org.apache.struts.action.RequestProcessor 并覆蓋了里面的方法。
sturts-config.xml 中
processorClass="org.springframework.web.struts.DelegatingRequestProcessor"/> 通過 來替代
org.apache.struts.action.RequestProcessor 的請求處理。
public class LoginAction extends Action {
//利用spring來注入這個(gè)對象。
private LoginDao dao ;
public void setDao(LoginDao dao) {
System.out.println("執(zhí)行注入");
this.dao = dao;
}
public LoginDao getDao() {
return dao;
}
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
LoginForm loginForm = (LoginForm) form;// TODO Auto-generated method stub
//這樣一改這行代碼似乎沒有必要了。
//WebApplicationContext ctx = this.getWebApplicationContext();
//LoginDao dao = (LoginDao) ctx.getBean("loginDao");
User u = new User();
u.setName(loginForm.getName());
u.setPwd(loginForm.getPwd());
//直接用dao來調(diào)用spring會(huì)將這個(gè)對象實(shí)例化。
if(dao.checkLogin(u)){
return mapping.findForward("success");
}else{
return mapping.findForward("error");
}
}
}
這里的。
LoginAction extends Action 說明 struts沒有和spring 耦合。
看一下
applicationContext.xml 中的配置。
<beans>
<bean id="loginDao" class="com.cao.dao.LoginDao"/>
<bean name="/login" class="com.cao.struts.action.LoginAction">
<property name="dao">
<ref local="loginDao"/>
</property>
</bean>
</beans>
|
這里 name="/login" 與struts 中的path匹配
class="com.cao.struts.action.LoginAction" 與struts 中的type匹配
還要為 LoginAction 提供必要的setXXX方法。 獲得ApplicationCotext和依賴注入的工作都在DelegatingRequestProcessor中完成。
3,全權(quán)委托:
Action 的創(chuàng)建和對象的依賴注入全部由IOC容器來完成。使用Spring的DelegatingAcionProxy來幫助實(shí)現(xiàn)代理的工作
org.springframework.web.struts.DelegatingActiongProxy繼承于org.apache.struts.action.Action .
全權(quán)委托的配置方式同 方式 2 類似 (applcationContext.xml文件的配置和 Action類的實(shí)現(xiàn)方式相同)。
<struts-config>
<data-sources />
<form-beans >
<form-bean name="loginForm"
type="com.cao.struts.form.LoginForm" />
</form-beans>
<global-exceptions />
<global-forwards />
<action-mappings >
<!-- type指向的是spring 的代理類 -->
<action
attribute="loginForm"
input="login.jsp"
name="loginForm"
path="/login"
scope="request"
type="org.springframework.web.struts.DelegatingActionProxy" >
<forward name="success" path="/ok.jsp" />
<forward name="error" path="/error.jsp" />
</action>
</action-mappings>
<message-resources parameter="com.cao.struts.ApplicationResources" />
<plug-in className=
"org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation"
value="/WEB-INF/applicationContext.xml"/>
</plug-in>
</struts-config>
不同之處
1, <action>中 type指向的是spring 的代理類
2, 去掉struts-config.xml中 <controller >
|
三種整和方式中我們優(yōu)先選用 全權(quán)委托的方式。
理由:
1,第一種使得過多的耦合了Spring和Action .
2,RequestProcessor類已經(jīng)被代理 如果要再實(shí)現(xiàn)自己的實(shí)現(xiàn)方式(如:編碼處理)怕有點(diǎn)麻煩。
總結(jié)一下:
整合工作中的步驟:
1,修改struts-config.xml
2, 配置applicationContext.xml
3, 為Action添加get/set方法 來獲得依賴注入的功能。
最近比較忙,但是每天網(wǎng)上還是的堅(jiān)持學(xué)點(diǎn),不積小流,無以成江河。
今天學(xué)jQuery對象訪問:
1.each(callback) 該方法以每一個(gè)匹配的元素作為上下文來執(zhí)行一個(gè)函數(shù),
在每次執(zhí)行函數(shù)時(shí),都會(huì)給函數(shù)傳遞一個(gè)表示作為執(zhí)行環(huán)境的元素在匹配的元素集合中所處位置的數(shù)字值作為參數(shù)(從0開始的int)
返回‘false’將停止循環(huán)(相當(dāng)于普通循環(huán)中使用的‘break’)
返回‘true’將跳至下一個(gè)循環(huán),(相當(dāng)于在普通的循環(huán)中使用‘continue’)
參數(shù):callback(function)
e.g1
<img/><img/>
jQuery代碼:
$('img').each(function(){
this.src="test"+i+".jpg";
});
e.g2
<button>Change colors</button>
<span></span>
<div></div>
<div></div>
<div></div>
<div></div>
<div id="stop">Stop here</div>
<div></div>
<div></div>
<div></div>
jQuery代碼:
$('button').click(function(){
$('div').each(function(index,domEle){//domEle ==this
$(domEle).css('backgroundColor',"yellow");
if($(this).is("#stop")){
$("span").text("stopped at div index #"+index);
return false;}
});});
2.size() 和length
都可以勇于得到j(luò)Query對象中元素的個(gè)數(shù),
返回: Number
e.g1
<img src="test1.jpg"/><img src="test2.jpg"/>
jQuery代碼:
$("img").size();
e.g2
同理:$("img").length;
3.get()取得所有匹配的DOM元素集合
返回:Array<Element>
e.g1
<img src="test1.jpg"/><img src="test2.jpg"/>
jQuery代碼:
$("img").get().reverse();
result:
[<img src="test1.jpg"/><img src="test2.jpg"/>]
4.get(index)
取得其中一個(gè)匹配元素,index表示取得第幾個(gè)匹配的元素
返回值:Element
HTML代碼:
<img src="test1.jpg"/><img src="test2.jpg"/>
jQuery代碼:
$("img").get(0);
result:
[<img src="test1.jpg"/>]
5.index(subject)
搜索與參數(shù)表示的對象匹配的元素,并返回相應(yīng)元素的索引值,
如果哦找到了匹配的元素,從0開始返回;如果沒有找到匹配的元素,返回-1
返回值;
Number
參數(shù):
subject(Element)
e.g1返回id值為foobar的元素的索引值
<div id="foobar"><div></div><div id="foo"></div></div>
jQuery代碼:
$("div").index($("#foobar")[0]) //0
$("div").index($('#foo')[0]) // 2
$("div").index($('#foo')) // -1
備注:
今天在瀏覽別人博客的時(shí)候看到的,收藏。
有時(shí)候,我們頁面當(dāng)中并不需要把要用到的JS全部加載出來,
這會(huì)使頁面加載時(shí)速度變慢~~~如果能按需加載,那能提高不少性能...也能節(jié)約不少流量~~~給用戶帶來好的體驗(yàn)~~
好比說,當(dāng)某個(gè)JS效果是觸發(fā)事件才顯示的...這個(gè)效果被封閉在一個(gè)JS中,,我想大家經(jīng)常這樣做吧~~這時(shí)候,我們能按需加載那就不必在頁面載入時(shí)去加載JS文件~~~這在jquery插件中很多。
用法:
1 , 當(dāng)在需要的時(shí)候再加載所需的javascript和css文件。
$.include('file/test.js')或$.include('file/test.css')
2, 當(dāng)然若你一次想加載多個(gè)文件你也可以這樣寫:
$.include(['file/test.js','file/test.css'])。
3, 因?yàn)檫@兩個(gè)文件的路徑相同,所以可以先指定路徑再加載所有文件:
$.ImportBasePath = 'file/';
$.include(['test.css','test.js']);
4, 你還可以加載完文件后執(zhí)行回調(diào)函數(shù)
$.include("file/test.css",function(){
alert("加載css后執(zhí)行");
});
插件下載地址:http://www.94this.com.cn/myCode/jqueryIncludefile/jqueryIncludefile.rar
注:jquery 自帶了有一個(gè)異步請求的方法,$.getScript ,可以異步加到JS并執(zhí)行
jQuery.getScript(url,[callback])
通過 HTTP GET 請求載入并執(zhí)行一個(gè) JavaScript 文件。
jQuery 1.2 版本之前,getScript 只能調(diào)用同域 JS 文件。 1.2中,您可以跨域調(diào)用 JavaScript 文件。注意:Safari 2 或更早的版本不能在全局作用域中同步執(zhí)行腳本。如果通過 getScript 加入腳本,請加入延時(shí)函數(shù)。
Loads, and executes, a local JavaScript file using an HTTP GET request.
Before jQuery 1.2, getScript was only able to load scripts from the same domain as the original page. As of 1.2, you can now load JavaScript files from any domain. Warning: Safari 2 and older is unable to evaluate scripts in a global context synchronously. If you load functions via getScript, make sure to call them after a delay.
返回值
XMLHttpRequest
參數(shù)
url (String) : 待載入 JS 文件地址。
callback (Function) : (可選) 成功載入后回調(diào)函數(shù)。
示例
載入 jQuery 官方顏色動(dòng)畫插件 成功后綁定顏色變化動(dòng)畫。
HTML 代碼:
<button id="go">» Run</button>
<div class="block"></div>
jQuery 代碼:
jQuery.getScript("http://dev.jquery.com/view/trunk/plugins/color/jquery.color.js",
function(){
$("#go").click(function(){
$(".block").animate( { backgroundColor: 'pink' }, 1000)
.animate( { backgroundColor: 'blue' }, 1000);
});
});
加載并執(zhí)行 test.js。
jQuery 代碼:
$.getScript("test.js");
加載并執(zhí)行 test.js ,成功后顯示信息。
jQuery 代碼:
$.getScript("test.js", function(){
alert("Script loaded and executed.");
});
jsp文件上傳大多采用采用開源項(xiàng)目來簡化處理,這里列出常用的兩個(gè)jar包的實(shí)現(xiàn),并進(jìn)行比較,說明他們的優(yōu)缺點(diǎn)和應(yīng)該注意的問題。
Commons FileUpload,可以在http://jakarta.apache.org/commons/fileupload/下載,這個(gè)包需要Commons IO的支持,可以在http://jakarta.apache.org/commons/io/下載
com.oreilly.servlet,可以在http://www.servlets.com/cos/下載
Commons FileUpload提供三種文件上傳處理方式,DiskFileUpload、ServletFileUpload和PortletFileUpload三種方式,其中DiskFileUpload已經(jīng)在javadoc下已經(jīng)被標(biāo)記為過期的方法,建議用ServletFileUpload代替,而PortletFileUpload需要配合portlet-api來使用,所以這里我們只介紹ServletFileUpload,并且這個(gè)也是最常用的。
com.oreilly.servlet也提供了三種文件上傳的處理方式,MultipartWrapper、MultipartRequest和MultipartParser三種方式,其中MultipartWrapper和MultipartRequest的用法基本相同,并且沒有MultipartRequest提供的操作多,所以這里介紹MultipartRequest,MultipartParser和前兩者有些不同,可以用來處理某些特殊情況,例如表單中有兩個(gè)同名的文件上傳選擇框。
我們暫時(shí)稱三面三種文件上傳方式分別為:ServletFileUpload方式(MultipartTestServlet)、MultipartRequest方式(MultipartTestServlet2)、MultipartParser方式(MultipartTestServlet3)
代碼如下:
test.html
<%@ page language="java" import="java.util.*" contentType="text/html;charset=gbk" pageEncoding="gbk"%>
<html>
<body>
<form action="MultipartTestServlet" enctype="multipart/form-data" method="post">
<input type="text" name="username" /><br />
<input type="file" name="myfile" /><br/>
<input type="file" name="myfile" /><br/>
<input type="submit" />
</form>
<br/><br/><br/><br/>
<form action="MultipartTestServlet2" enctype="multipart/form-data" method="post">
<input type="text" name="username" /><br />
<input type="file" name="myfile" /><br/>
<input type="file" name="myfile" /><br/>
<input type="submit" />
</form>
<br/><br/><br/><br/>
<form action="MultipartTestServlet3" enctype="multipart/form-data" method="post">
<input type="text" name="username" /><br />
<input type="file" name="myfile" /><br/>
<input type="file" name="myfile" /><br/>
<input type="submit" />
</form>
</body>
</html>
MultipartTestServlet.java
package com.bug.servlet;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUpload;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.RequestContext;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.servlet.ServletRequestContext;
public class MultipartTestServlet extends HttpServlet {
public MultipartTestServlet() {
super();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("gbk");
RequestContext requestContext = new ServletRequestContext(request);
if(FileUpload.isMultipartContent(requestContext)){
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setRepository(new File("c:/tmp/"));
ServletFileUpload upload = new ServletFileUpload(factory);
//upload.setHeaderEncoding("gbk");
upload.setSizeMax(2000000);
List items = new ArrayList();
try {
items = upload.parseRequest(request);
} catch (FileUploadException e1) {
System.out.println("文件上傳發(fā)生錯(cuò)誤" + e1.getMessage());
}
Iterator it = items.iterator();
while(it.hasNext()){
FileItem fileItem = (FileItem) it.next();
if(fileItem.isFormField()){
System.out.println(fileItem.getFieldName() + " " + fileItem.getName() + " " + new String(fileItem.getString().getBytes("iso8859-1"), "gbk"));
}else{
System.out.println(fileItem.getFieldName() + " " +
fileItem.getName() + " " +
fileItem.isInMemory() + " " +
fileItem.getContentType() + " " +
fileItem.getSize());
if(fileItem.getName()!=null && fileItem.getSize()!=0){
File fullFile = new File(fileItem.getName());
File newFile = new File("c:/temp/" + fullFile.getName());
try {
fileItem.write(newFile);
} catch (Exception e) {
e.printStackTrace();
}
}else{
System.out.println("文件沒有選擇 或 文件內(nèi)容為空");
}
}
}
}
}
}
MultipartTestServlet2.java
package com.bug.servlet;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;
public class MultipartTestServlet2 extends HttpServlet {
public MultipartTestServlet2() {
super();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//request.setCharacterEncoding("gbk"); 不起作用
System.out.println("start ");
MultipartRequest multi = new MultipartRequest(request, "c:/tmp/", 2*1024*1024, "gbk", new DefaultFileRenamePolicy());
System.out.println("start ");
Enumeration filesName = multi.getFileNames();
Enumeration paramsName = multi.getParameterNames();
while(paramsName.hasMoreElements()){
String paramName = (String) paramsName.nextElement();
System.out.println(multi.getParameter(paramName));
}
while(filesName.hasMoreElements()){
String fileName = (String) filesName.nextElement();
System.out.println(multi.getFilesystemName(fileName) + " " +
multi.getOriginalFileName(fileName) + " " +
multi.getContentType(fileName) + " ");
if(multi.getFilesystemName(fileName)!=null && !multi.getFilesystemName(fileName).equals(""))
System.out.println(multi.getFile(fileName).toURI());
}
}
}
MultipartTestServlet3.java
package com.bug.servlet;
import java.io.File;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.oreilly.servlet.multipart.FilePart;
import com.oreilly.servlet.multipart.MultipartParser;
import com.oreilly.servlet.multipart.ParamPart;
import com.oreilly.servlet.multipart.Part;
public class MultipartTestServlet3 extends HttpServlet {
public MultipartTestServlet3() {
super();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
MultipartParser mp = new MultipartParser(request, 2*1024*1024, false, false, "gbk");
Part part;
while ((part = mp.readNextPart()) != null) {
String name = part.getName();
if (part.isParam()) {
ParamPart paramPart = (ParamPart) part;
String value = paramPart.getStringValue();
System.out.println("param: name=" + name + "; value=" + value);
}
else if (part.isFile()) {
// it's a file part
FilePart filePart = (FilePart) part;
String fileName = filePart.getFileName();
if (fileName != null) {
long size = filePart.writeTo(new File("c:/tmp/"));
System.out.println("file: name=" + name + "; fileName=" + fileName +
", filePath=" + filePart.getFilePath() +
", contentType=" + filePart.getContentType() +
", size=" + size);
}
else {
System.out.println("file: name=" + name + "; EMPTY");
}
System.out.flush();
}
}
}
}
web.xml中加入
<servlet>
<servlet-name>MultipartTestServlet</servlet-name>
<servlet-class>com.bug.servlet.MultipartTestServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>MultipartTestServlet2</servlet-name>
<servlet-class>com.bug.servlet.MultipartTestServlet2</servlet-class>
</servlet>
<servlet>
<servlet-name>MultipartTestServlet3</servlet-name>
<servlet-class>com.bug.servlet.MultipartTestServlet3</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MultipartTestServlet</servlet-name>
<url-pattern>/MultipartTestServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MultipartTestServlet2</servlet-name>
<url-pattern>/MultipartTestServlet2</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MultipartTestServlet3</servlet-name>
<url-pattern>/MultipartTestServlet3</url-pattern>
</servlet-mapping>
問題1、中文問題:
三種凡是都可以通過自己的方法來設(shè)置encoding為gbk開處理和解決中文問題,包括初始化的時(shí)候傳入gbk作為參數(shù),或是是初始化后通過setEncoding的方式來實(shí)現(xiàn)。
另外ServletFileUpload方式也可以通過request.setCharacterEncoding("gbk");的方式來實(shí)現(xiàn),而其它兩種方式不支持這種方式。
問題2、文件大小限制
ServletFileUpload方式可以設(shè)置文件大小限制,也可以不用設(shè)置,例子中的upload.setSizeMax(2000000)就可以注釋掉。如果設(shè)置upload.setSizeMax(-1),表明不限制上傳的大小。文檔中沒有指明默認(rèn)的限制的多少,我在不設(shè)置的情況下上傳了一個(gè)9M的東西,可以上傳,估計(jì)默認(rèn)是不限制大小的。
而MultipartRequest方式和MultipartParser方式是必須設(shè)置文件的上傳文件的大小限制的,如果不設(shè)置,默認(rèn)是1M的大小限制。
問題3、文件上傳發(fā)生錯(cuò)誤
如果文件上傳過程中發(fā)生任何錯(cuò)誤,或者是文件的大小超出了范圍,系統(tǒng)都將拋出錯(cuò)誤。
ServletFileUpload方式在upload.parseRequest(request)時(shí)拋出錯(cuò)誤
MultipartRequest方式在new MultipartRequest(。。。)時(shí)拋出錯(cuò)誤
MultipartParser方式在new MultipartParser(。。。)時(shí)拋出錯(cuò)誤
問題4、上傳同名文件時(shí),他們保存到臨時(shí)目錄是的沖突問題
ServletFileUpload方式,不會(huì)有沖突,系統(tǒng)會(huì)把上傳得文件按照一定的規(guī)則重新命名,保證不會(huì)沖突
MultipartParser方式,會(huì)產(chǎn)生沖突,系統(tǒng)會(huì)把文件按照上傳時(shí)的文件名,保存到臨時(shí)目錄下,如果兩個(gè)用會(huì)同時(shí)上傳文件名相同的文件,那么就可能會(huì)產(chǎn)生沖突,一方把另一方的臨時(shí)文件給替換了。
MultipartRequest方式,在初始化時(shí)如果提供了一個(gè)名稱轉(zhuǎn)換策略,就不會(huì)有沖突,如果不提桶,就會(huì)有沖突。在上面的例子中我們提供了一個(gè)new DefaultFileRenamePolicy()保證了文件名不會(huì)有沖突發(fā)生。
問題5:表單中有兩個(gè)同名的文件上傳選擇框,就像我們例子中的myfile一樣,每個(gè)表單中有兩個(gè)name=“myfile”的上傳框
ServletFileUpload方式,可以處理,可以分別得到他們各自的文件,
MultipartRequest方式,不可以處理,會(huì)發(fā)生沖突,會(huì)有一個(gè)上傳框的文件覆蓋了另外一個(gè)。
MultipartParser方式,可以處理,可以分別得到他們各自的文件,
備注:
代碼比較亂,主要是為了說明他們間的區(qū)別。他們的詳細(xì)地使用說明還是要參考他的javadoc和domo。
參考:
1、http://www.servlets.com/cos/#classes
2、http://jakarta.apache.org/commons/fileupload/apidocs/index.html
3、http://jakarta.apache.org/commons/fileupload/using.html
4、http://www.onjava.com/pub/a/onjava/2003/06/25/commons.html?page=3
//先鎖表,然后再判斷是否已經(jīng)存在數(shù)據(jù),以防止出現(xiàn)重復(fù)行
String lockSql = "update YHZHMX set YHZHMX_DJBH=YHZHMX_DJBH where 1=2";
//上面的語法貌似不好用.故采用下面的語法
lockSql = "SELECT * FROM YHZHMX FOR UPDATE";