久久riav二区三区,岛国av一区,精品久久久久99http://www.aygfsteel.com/wuhen86/Jump Over yourself !zh-cnThu, 19 Jun 2025 10:13:58 GMTThu, 19 Jun 2025 10:13:58 GMT60JAVA中的反射機(jī)制http://www.aygfsteel.com/wuhen86/articles/355219.html無(wú)很無(wú)很Thu, 28 Jul 2011 05:45:00 GMThttp://www.aygfsteel.com/wuhen86/articles/355219.htmlhttp://www.aygfsteel.com/wuhen86/comments/355219.htmlhttp://www.aygfsteel.com/wuhen86/articles/355219.html#Feedback0http://www.aygfsteel.com/wuhen86/comments/commentRss/355219.htmlhttp://www.aygfsteel.com/wuhen86/services/trackbacks/355219.htmlJAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為java語(yǔ)言的反射機(jī)制。
Java反射機(jī)制主要提供了以下功能: 在運(yùn)行時(shí)分析類的能力,判斷任意對(duì)象所屬類,類中有哪些方法,有哪些成員變量;在運(yùn)行時(shí)控查對(duì)象,比如,只寫一個(gè)toString()方法供所有的類使用;實(shí)現(xiàn)通用數(shù)組操作代碼的功能。

1. 得到某個(gè)對(duì)象的屬性
1 public Object getProperty(Object owner, String fieldName) throws Exception {
2      Class ownerClass = owner.getClass();
3
4      Field field = ownerClass.getField(fieldName);
5
6      Object property = field.get(owner);
7
8      return property;
9 }
Class ownerClass = owner.getClass():得到該對(duì)象的Class。
Field field = ownerClass.getField(fieldName):通過(guò)Class得到類聲明的屬性。
Object property = field.get(owner):通過(guò)對(duì)象得到該屬性的實(shí)例,如果這個(gè)屬性是非公有的,這里會(huì)報(bào)IllegalAccessException。
2. 得到某個(gè)類的靜態(tài)屬性
1 public Object getStaticProperty(String className, String fieldName)
2              throws Exception {
3      Class ownerClass = Class.forName(className);
4
5      Field field = ownerClass.getField(fieldName);
6
7      Object property = field.get(ownerClass);
8
9      return property;
10 }
Class ownerClass = Class.forName(className) :首先得到這個(gè)類的Class。
Field field = ownerClass.getField(fieldName):和上面一樣,通過(guò)Class得到類聲明的屬性。
Object property = field.get(ownerClass) :這里和上面有些不同,因?yàn)樵搶傩允庆o態(tài)的,所以直接從類的Class里取。
3. 執(zhí)行某對(duì)象的方法
1 public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {
2
3      Class ownerClass = owner.getClass();
4
5      Class[] argsClass = new Class[args.length];
6
7      for (int i = 0, j = args.length; i < j; i++) {
8          argsClass[i] = args[i].getClass();
9      }
10
11      Method method = ownerClass.getMethod(methodName, argsClass);
12
13      return method.invoke(owner, args);
14 }
Class owner_class = owner.getClass() :首先還是必須得到這個(gè)對(duì)象的Class。
5~9行:配置參數(shù)的Class數(shù)組,作為尋找Method的條件。
Method method = ownerClass.getMethod(methodName, argsClass):通過(guò)Method名和參數(shù)的Class數(shù)組得到要執(zhí)行的Method。
method.invoke(owner, args):執(zhí)行該Method,invoke方法的參數(shù)是執(zhí)行這個(gè)方法的對(duì)象,和參數(shù)數(shù)組。返回值是Object,也既是該方法的返回值。
4. 執(zhí)行某個(gè)類的靜態(tài)方法
1 public Object invokeStaticMethod(String className, String methodName,
2              Object[] args) throws Exception {
3      Class ownerClass = Class.forName(className);
4
5      Class[] argsClass = new Class[args.length];
6
7      for (int i = 0, j = args.length; i < j; i++) {
8          argsClass[i] = args[i].getClass();
9      }
10
11      Method method = ownerClass.getMethod(methodName, argsClass);
12
13      return method.invoke(null, args);
14 }
基本的原理和實(shí)例3相同,不同點(diǎn)是最后一行,invoke的一個(gè)參數(shù)是null,因?yàn)檫@是靜態(tài)方法,不需要借助實(shí)例運(yùn)行。
5. 新建實(shí)例
1
2 public Object newInstance(String className, Object[] args) throws Exception {
3      Class newoneClass = Class.forName(className);
4
5      Class[] argsClass = new Class[args.length];
6
7      for (int i = 0, j = args.length; i < j; i++) {
8          argsClass[i] = args[i].getClass();
9      }
10
11      Constructor cons = newoneClass.getConstructor(argsClass);
12
13      return cons.newInstance(args);
14
15 }
這里說(shuō)的方法是執(zhí)行帶參數(shù)的構(gòu)造函數(shù)來(lái)新建實(shí)例的方法。如果不需要參數(shù),可以直接使用newoneClass.newInstance()來(lái)實(shí)現(xiàn)。
Class newoneClass = Class.forName(className):第一步,得到要構(gòu)造的實(shí)例的Class。
第5~第9行:得到參數(shù)的Class數(shù)組。
Constructor cons = newoneClass.getConstructor(argsClass):得到構(gòu)造子。
cons.newInstance(args):新建實(shí)例。
6. 判斷是否為某個(gè)類的實(shí)例
1 public boolean isInstance(Object obj, Class cls) {
2      return cls.isInstance(obj);
3 }
7. 得到數(shù)組中的某個(gè)元素
1 public Object getByArray(Object array, int index) {
2      return Array.get(array,index);
3 }
其中,反射機(jī)制最重要的部分是允許你檢查類的結(jié)構(gòu)。java.lang.reflect包中的三個(gè)類Field,Method,Constructor類分別描述類的字段,方法和構(gòu)造器,它們都有一個(gè)getName方法,用來(lái)返回相應(yīng)條目的名稱。



無(wú)很 2011-07-28 13:45 發(fā)表評(píng)論
]]>
java中讀取配置文件信息的六種方法http://www.aygfsteel.com/wuhen86/articles/355218.html無(wú)很無(wú)很Thu, 28 Jul 2011 05:34:00 GMThttp://www.aygfsteel.com/wuhen86/articles/355218.htmlhttp://www.aygfsteel.com/wuhen86/comments/355218.htmlhttp://www.aygfsteel.com/wuhen86/articles/355218.html#Feedback0http://www.aygfsteel.com/wuhen86/comments/commentRss/355218.htmlhttp://www.aygfsteel.com/wuhen86/services/trackbacks/355218.html1。使用Java.util.Properties類的load()方法
示例: InputStream in = lnew BufferedInputStream(new FileInputStream(name));
Properties p = new Properties();
p.load(in);

2。使用java.util.ResourceBundle類的getBundle()方法
示例: ResourceBundle rb = ResourceBundle.getBundle(name, Locale.getDefault());

3。使用java.util.PropertyResourceBundle類的構(gòu)造函數(shù)
示例: InputStream in = new BufferedInputStream(new FileInputStream(name));
ResourceBundle rb = new PropertyResourceBundle(in);

4。使用class變量的getResourceAsStream()方法
示例: InputStream in = JProperties.class.getResourceAsStream(name);
Properties p = new Properties();
p.load(in);

5。使用class.getClassLoader()所得到的java.lang.ClassLoader的getResourceAsStream()方法
示例: InputStream in = JProperties.class.getClassLoader().getResourceAsStream(name);
Properties p = new Properties();
p.load(in);

6。使用java.lang.ClassLoader類的getSystemResourceAsStream()靜態(tài)方法



無(wú)很 2011-07-28 13:34 發(fā)表評(píng)論
]]>
JAVA深入探索-參數(shù)傳遞http://www.aygfsteel.com/wuhen86/articles/355216.html無(wú)很無(wú)很Thu, 28 Jul 2011 05:31:00 GMThttp://www.aygfsteel.com/wuhen86/articles/355216.htmlhttp://www.aygfsteel.com/wuhen86/comments/355216.htmlhttp://www.aygfsteel.com/wuhen86/articles/355216.html#Feedback0http://www.aygfsteel.com/wuhen86/comments/commentRss/355216.htmlhttp://www.aygfsteel.com/wuhen86/services/trackbacks/355216.html按值傳參
JAVA中的參數(shù)傳遞只存在傳值方式一種,但也有傳引用的概念。
這是java參數(shù)傳遞的核心說(shuō)明。java不像C/C++那樣可以通過(guò)指針?lè)虻刂贩麃?lái)區(qū)分傳值還是傳引用,因?yàn)樗挥幸环N參數(shù)傳遞的方式,那就是傳值方式。這對(duì)初學(xué)java的人來(lái)說(shuō)很難理解,通過(guò)下面的例子可以看出真正的傳值在java中是如何實(shí)現(xiàn)的。
public static void swap(int a,int b){//交換兩個(gè)變量的值
       int temp = a;
       a = b;
       b = temp;
       System.out.println("swap:"+a+","+b);
}
......
    int a = 3;
int b = 5;
   swap(a,b);
       System.out.println(a +" "+b);//3 5
......
程序打印結(jié)果:
swap:5,3
3   5
由程序的結(jié)果可以看到,事實(shí)上,經(jīng)過(guò)交換的方法swap()之后,主程序中的變量a,b的值并沒(méi)有被改變。
分析過(guò)程如下:在調(diào)用swap()方法的時(shí)候,程序把a(bǔ)、b的副本送到swap()方法中的變量a、b中去,而主程序中的變量a、b中的內(nèi)容并沒(méi)有被改變。所以就會(huì)出現(xiàn)上面的結(jié)果。
其實(shí),不僅是簡(jiǎn)單的數(shù)據(jù)類型如此 ,如果傳遞的參數(shù)是一個(gè)對(duì)象,也會(huì)出現(xiàn)這樣的結(jié)果,這與簡(jiǎn)單數(shù)據(jù)類型的情況類似,都可以劃為按值傳參一類中。我們看下面的程序及其分析過(guò)程:
public class User{
static void swap(User user1,User user2){
       User user = user1;
       user1 = user2;
       user2 = user;
}
public static void main(String[]args){
       User user3 = new User("ding", 20);
       User user4 = new User("zhao", 18);
       swap(user3, user4);  
   /*進(jìn)行函數(shù)swap(user1,user2)的調(diào)用,但是并不會(huì)真正把user3和user4所指向的內(nèi)存空間
      *進(jìn)行交換,只是在調(diào)用的時(shí)候,會(huì)把user3中存放的內(nèi)存地址復(fù)制一份傳給user1,把user4中存放的
      *內(nèi)存地址復(fù)制一份傳給user2,相當(dāng)于只是給user1和user2了一個(gè)副本,而真正的對(duì)象
      *user3和user4并沒(méi)有在swap()函數(shù)中被觸及。所以函數(shù)處理的結(jié)果是使user1和user2所指向的內(nèi)存空間
      *進(jìn)行交換,而user3和user4中的存放內(nèi)容仍是原來(lái)的內(nèi)容。*/
       System.out.println(user3.username + "   " +user3.age);//ding   20
       System.out.println(user4.username + "   " +user4.age);//zhao   18

程序的運(yùn)行結(jié)果:
ding   20
zhao   18

傳遞引用
既然說(shuō)java中的參數(shù)傳遞只有by value一種,為什么還要說(shuō)傳遞引用呢?實(shí)際上,java與C++一樣,同樣存在對(duì)一個(gè)對(duì)象的引用進(jìn)行傳遞的問(wèn)題,但java中的引用傳遞機(jī)制是,把原來(lái)變量中保存的內(nèi)存地址傳遞作為一個(gè)參數(shù)進(jìn)行傳遞,而不是直接把引用傳過(guò)去。所以在java中仍把它稱做按值傳參。
同樣采用例子的方式來(lái)解釋java中的引用傳遞的問(wèn)題:
.......
public static   void changAge(User user){
       User temp = user;//這時(shí),temp中存放了和原對(duì)象相同的內(nèi)存地址
       temp.age = temp.age + 20;//對(duì)user的年齡進(jìn)行增加的操作,
       /*是對(duì)temp所指向的內(nèi)存空間中的值直接進(jìn)行操作,所以會(huì)對(duì)原對(duì)象的值造成影響。就相當(dāng)于是傳遞了原對(duì)象的引用*/
}
......
       User user = new User("li",25);//仍采用上例中的User
       changAge(user);//改變user的年齡
       System.out.println(user.age);//45
.......
有了上面例子的說(shuō)明,我們可能就會(huì)想到,如果我們的程序中私有變量是一個(gè)對(duì)象類型的變量時(shí),在主程序中有了這個(gè)私有變量的拷貝,是不是就有可能在修改這個(gè)拷貝時(shí)不小心把原來(lái)的私有變量的值也給改變了呢?
我們來(lái)看下面的例子:
class Test{
private Date date=new Date();
public Date getDate(){
return date;
}
public static void main(String[] args){
Test tt=new Test();
Date myDate=tt.getDate();//返回了一個(gè)私有變量的拷貝
System.out.println(myDate);
myDate.setTime(new Date().getTime()-(long)(10*365.25*24*3600*1000));//對(duì)新產(chǎn)生的拷貝進(jìn)行修改
System.out.println(tt.getDate());
System.out.println(myDate);
}
}
先來(lái)猜一下運(yùn)行的結(jié)果,是前兩句輸出一樣呢還是后兩句輸出一樣(最后一句輸出比第一句輸出的日期早十年)?很多人都會(huì)說(shuō)是前兩句輸出一樣.實(shí)際上,你會(huì)驚奇地發(fā)現(xiàn),輸出結(jié)果顯示后兩者輸出一樣,私有變量在程序外部被改變了,程序的封裝性遭到了破壞。
出錯(cuò)的原因很微妙.因?yàn)閙yDate和tt指向了同一個(gè)對(duì)象,對(duì)myDate的引用更改方法自動(dòng)地改變了這個(gè)類的私有方法狀態(tài)。經(jīng)過(guò)測(cè)試可以知道,如果myDate被重新賦值(比如myDate=new Date()),就不會(huì)出現(xiàn)上面的結(jié)果。但是現(xiàn)在的這個(gè)程序,私有變量還是在程序外部被改變了。
如果需要返回一個(gè)指向可變對(duì)象的引用,我們就需要克隆它,這樣就不會(huì)導(dǎo)致上面的私有變量被更改。
上面程序就應(yīng)更改為:return (Date)date.clone();就可以防止私有變量被修改的麻煩了。
再來(lái)執(zhí)行上面的程序,就會(huì)出現(xiàn)不一樣的結(jié)果。



無(wú)很 2011-07-28 13:31 發(fā)表評(píng)論
]]>
使用JNI技術(shù)實(shí)現(xiàn)JAVA程序調(diào)用dllhttp://www.aygfsteel.com/wuhen86/articles/355212.html無(wú)很無(wú)很Thu, 28 Jul 2011 04:37:00 GMThttp://www.aygfsteel.com/wuhen86/articles/355212.htmlhttp://www.aygfsteel.com/wuhen86/comments/355212.htmlhttp://www.aygfsteel.com/wuhen86/articles/355212.html#Feedback0http://www.aygfsteel.com/wuhen86/comments/commentRss/355212.htmlhttp://www.aygfsteel.com/wuhen86/services/trackbacks/355212.htmlJAVA的跨平臺(tái)的特性深受java程序員們的喜愛(ài),但正是由于它為了實(shí)現(xiàn)跨平臺(tái)的目的,使得它和本地機(jī)器的各種內(nèi)部聯(lián)系變得很少,大大約束了它的功能,比如與一些硬件設(shè)備通信,往往要花費(fèi)很大的精力去設(shè)計(jì)流程編寫代碼去管理設(shè)備端口,而且有一些設(shè)備廠商提供的硬件接口已經(jīng)經(jīng)過(guò)一定的封裝和處理,不能直接使用java程序通過(guò)端口和設(shè)備通信,這種情況下就得考慮使用java程序去調(diào)用比較擅長(zhǎng)同系統(tǒng)打交道的第三方程序,從1.1版本開(kāi)始的JDK提供了解決這個(gè)問(wèn)題的技術(shù)標(biāo)準(zhǔn):JNI技術(shù).
       JNI是Java Native Interface(Java本地接口)的縮寫,本地是相對(duì)于java程序來(lái)說(shuō)的,指直接運(yùn)行在操作系統(tǒng)之上,與操作系統(tǒng)直接交互的程序.從1.1版本的JDK開(kāi)始,JNI就作為標(biāo)準(zhǔn)平臺(tái)的一部分發(fā)行.在JNI出現(xiàn)的初期是為了Java程序與本地已編譯語(yǔ)言,尤其是C和C++的互操作而設(shè)計(jì)的,后來(lái)經(jīng)過(guò)擴(kuò)展也可以與c和c++之外的語(yǔ)言編寫的程序交互,例如Delphi程序.
       使用JNI技術(shù)固然增強(qiáng)了java程序的性能和功能,但是它也破壞了java的跨平臺(tái)的優(yōu)點(diǎn),影響程序的可移植性和安全性,例如由于其他語(yǔ)言(如C/C++)可能能夠隨意地分配對(duì)象/占用內(nèi)存,Java的指針安全性得不到保證.但在有些情況下,使用JNI是可以接受的,甚至是必須的,例如上面提到的使用java程序調(diào)用硬件廠商提供的類庫(kù)同設(shè)備通信等,目前市場(chǎng)上的許多讀卡器設(shè)備就是這種情況.在這必須使用JNI的情況下,盡量把所有本地方法都封裝在單個(gè)類中,這個(gè)類調(diào)用單個(gè)的本地庫(kù)文件,并保證對(duì)于每種目標(biāo)操作系統(tǒng),都可以用特定于適當(dāng)平臺(tái)的版本替換這個(gè)文件,這樣使用JNI得到的要比失去的多很多.
       現(xiàn)在開(kāi)始討論上面提到的問(wèn)題,一般設(shè)備商會(huì)提供兩種類型的類庫(kù)文件,windows系統(tǒng)的會(huì)包含.dll/.h/.lib文件,而linux系統(tǒng)的會(huì)包含.so/.a文件,這里只討論windows系統(tǒng)下的c/c++編譯的dll文件調(diào)用方法.
       我把設(shè)備商提供的dll文件稱之為第三方dll文件,之所以說(shuō)第三方,是因?yàn)镴NI直接調(diào)用的是按它的標(biāo)準(zhǔn)使用c/c++語(yǔ)言編譯的dll文件,這個(gè)文件是客戶程序員按照設(shè)備商提供的.h文件中的列出的方法編寫的dll文件,我稱之為第二方dll文件,真正調(diào)用設(shè)備商提供的dll文件的其實(shí)就是這個(gè)第二方dll文件.到這里,解決問(wèn)題的思路已經(jīng)產(chǎn)生了,大慨分可以分為三步:
       1>編寫一個(gè)java類,這個(gè)類包含的方法是按照設(shè)備商提供的.h文件經(jīng)過(guò)變形/轉(zhuǎn)換處理過(guò)的,并且必須使用native定義.這個(gè)地方需要注意的問(wèn)題是java程序中定義的方法不必追求和廠商提供的頭文件列出的方法清單中的方法具有相同的名字/返回值/參數(shù),因?yàn)橐恍﹨?shù)類型如指針等在java中沒(méi)法模擬,只要能保證這個(gè)方法能實(shí)現(xiàn)原dll文件中的方法提供的功能就行了;
       2>按JNI的規(guī)則使用c/c++語(yǔ)言編寫一個(gè)dll程序;
       3>按dll調(diào)用dll的規(guī)則在自己編寫的dll程序里面調(diào)用廠商提供的dll程序中定義的方法.

       我之前為了給一個(gè)java項(xiàng)目添加IC卡讀寫功能,曾經(jīng)查了很多資料發(fā)現(xiàn)查到的資料都是只說(shuō)到第二步,所以剩下的就只好自己動(dòng)手研究了.下面結(jié)合具體的代碼來(lái)按這三個(gè)步驟分析.

     1>假設(shè)廠商提供的.h文件中定義了一個(gè)我們需要的方法:
      __int16 __stdcall readData( HANDLE icdev, __int16 offset, __int16 len, unsigned char *data_buffer );
      a.__int16定義了一個(gè)不依賴于具體的硬件和軟件環(huán)境,在任何環(huán)境下都占16 bit的整型數(shù)據(jù)(java中的int類型是32 bit),這個(gè)數(shù)據(jù)類型是vc++中特定的數(shù)據(jù)類型,所以我自己做的dll也是用的vc++來(lái)編譯.
     b.__stdcall表示這個(gè)函數(shù)可以被其它程序調(diào)用,vc++編譯的DLL欲被其他語(yǔ)言編寫的程序調(diào)用,應(yīng)將函數(shù)的調(diào)用方式聲明為_(kāi)_stdcall方式,WINAPI都采用這種方式.c/c++語(yǔ)言默認(rèn)的調(diào)用方式是__cdecl,所以在自己做可被java程序調(diào)用的dll時(shí)一定要加上__stdcall的聲明,否則在java程序執(zhí)行時(shí)會(huì)報(bào)類型不匹配的錯(cuò)誤.
     c.HANDLE icdev是windows操作系統(tǒng)中的一個(gè)概念,屬于win32的一種數(shù)據(jù)類型,代表一個(gè)核心對(duì)象在某一個(gè)進(jìn)程中的唯一索引,不是指針,在知道這個(gè)索引代表的對(duì)象類型時(shí)可以強(qiáng)制轉(zhuǎn)換成此類型的數(shù)據(jù).
    這些知識(shí)都屬于win32編程的范圍,更為詳細(xì)的win32資料可以查閱相關(guān)的文檔.
    這個(gè)方法的原始含義是通過(guò)設(shè)備初始時(shí)產(chǎn)生的設(shè)備標(biāo)志號(hào)icdev,讀取從某字符串在內(nèi)存空間中的相對(duì)超始位置offset開(kāi)始的共len個(gè)字符,并存放到data_buffer指向的無(wú)符號(hào)字符類型的內(nèi)存空間中,并返回一個(gè)16 bit的整型值來(lái)標(biāo)志這次的讀設(shè)備是否成功,這里真正需要的是unsigned char *這個(gè)指針指向的地址存放的數(shù)據(jù),而java中沒(méi)有指針類型,所以可以考慮定義一個(gè)返回字符串類型的java方法,原方法中返回的整型值也可以按經(jīng)過(guò)一定的規(guī)則處理按字符串類型傳出,由于HANDLE是一個(gè)類型于java中的Ojbect類型的數(shù)據(jù),可以把它當(dāng)作int類型處理,這樣java程序中的方法定義就已經(jīng)形成了:
    String readData( int icdev, int offset, int len );
    聲明這個(gè)方法的時(shí)候要加上native關(guān)鍵字,表明這是一個(gè)與本地方法通信的java方法,同時(shí)為了安全起見(jiàn),此文方法要對(duì)其它類隱藏,使用private聲明,再另外寫一個(gè)public方法去調(diào)用它,同時(shí)要在這個(gè)類中把本地文件加載進(jìn)來(lái),最終的代碼如下:

package test;

public class LinkDll
{
    //從指定地址讀數(shù)據(jù)
    private native String readData( int icdev, int offset, int len );
    public String readData( int icdev, int offset, int len )
    {
        return this.readDataTemp( icdev, offset, len );
    }

    static 
    {        
        System.loadLibrary( "TestDll" );//如果執(zhí)行環(huán)境是linux這里加載的是SO文件,如果是windows環(huán)境這里加載的是dll文件
    }
}

2>使用JDK的javah命令為這個(gè)類生成一個(gè)包含類中的方法定義的.h文件,可進(jìn)入到class文件包的根目錄下(只要是在classpath參數(shù)中的路徑即可),使用javah命令的時(shí)候要加上包名javah test.LinkDll,命令成功后生成一個(gè)名為test_LinkDll.h的頭文件.
    文件內(nèi)容如下:

/* DO NOT EDIT THIS FILE - it is machine generated*/
#include <jni.h>

/* Header for class test_LinkDll */
#ifndef _Included_test_LinkDll #define

Included_test_LinkDll
#ifdef __cplusplus extern "C" { #endif
/*
* Class:     test_LinkDll
* Method:    readDataTemp
* Signature: (III)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_test_LinkDll_readDataTemp(JNIEnv *, jobject, jint, jint, jint);
#ifdef __cplusplus } #endif
#endif

    可以看出,JNI為了實(shí)現(xiàn)和dll文件的通信,已經(jīng)按它的標(biāo)準(zhǔn)對(duì)方法名/參數(shù)類型/參數(shù)數(shù)目作了一定的處理,其中的JNIEnv*/jobjtct這兩個(gè)參數(shù)是每個(gè)JNI方法固有的參數(shù),javah命令負(fù)責(zé)按JNI標(biāo)準(zhǔn)為每個(gè)java方法加上這兩個(gè)參數(shù).JNIEnv是指向類型為JNIEnv_的一個(gè)特殊JNI數(shù)據(jù)結(jié)構(gòu)的指針,當(dāng)由C++編譯器編譯時(shí)JNIEnv_結(jié)構(gòu)其實(shí)被定義為一個(gè)類,這個(gè)類中定義了很多內(nèi)嵌函數(shù),通過(guò)使用"->"符號(hào),可以很方便使用這些函數(shù),如:
    (env)->NewString( jchar* c, jint len )
    可以從指針c指向的地址開(kāi)始讀取len個(gè)字符封裝成一個(gè)JString類型的數(shù)據(jù).
    其中的jchar對(duì)應(yīng)于c/c++中的char,jint對(duì)應(yīng)于c/c++中的len,JString對(duì)應(yīng)于java中的String,通過(guò)查看jni.h可以看到這些數(shù)據(jù)類型其實(shí)都是根據(jù)java和c/c++中的數(shù)據(jù)類型對(duì)應(yīng)關(guān)系使用typedef關(guān)鍵字重新定義的基本數(shù)據(jù)類型或結(jié)構(gòu)體.
    具體的對(duì)應(yīng)關(guān)系如下:
Java類型     本地類型             描述
boolean       jboolean             C/C++8位整型
byte             jbyte                   C/C++帶符號(hào)的8位整型
char             jchar                   C/C++無(wú)符號(hào)的16位整型
short            jshort                  C/C++帶符號(hào)的16位整型
int                 jint                      C/C++帶符號(hào)的32位整型
long             jlong                   C/C++帶符號(hào)的64位整型e
float             jfloat                   C/C++32位浮點(diǎn)型
double        jdouble               C/C++64位浮點(diǎn)型
Object          jobject                 任何Java對(duì)象,或者沒(méi)有對(duì)應(yīng)java類型的對(duì)象
Class         jclass                  Class對(duì)象
String          jstring                  字符串對(duì)象
Object[]      jobjectArray         任何對(duì)象的數(shù)組
boolean[]    jbooleanArray     布爾型數(shù)組
byte[]          jbyteArray           比特型數(shù)組
char[]           jcharArray            字符型數(shù)組
short[]          jshortArray           短整型數(shù)組
int[]             jintArray                整型數(shù)組
long[]          jlongArray             長(zhǎng)整型數(shù)組
float[]         jfloatArray              浮點(diǎn)型數(shù)組
double[]     jdoubleArray        雙浮點(diǎn)型數(shù)組
    更為詳細(xì)的資料可以查閱JNI文檔.
    需要注意的問(wèn)題:test_LinkDll.h文件包含了jni.h文件;

3>使用vc++ 6.0編寫TestDll.dll文件,這個(gè)文件名是和java類中l(wèi)oadLibrary的名稱一致.
a>使用vc++6.0 新建一個(gè)Win32 Dynamic-Link Library的工程文件,工程名指定為TestDll
b>把源代碼文件和頭文件使用"Add Fiels to Project"菜單加載到工程中,若使用c來(lái)編碼,源碼文件后綴名為.c,若使用c++來(lái)編碼,源碼文件擴(kuò)展名為.cpp,這個(gè)一定要搞清楚,因?yàn)閷?duì)于不同的語(yǔ)言,使用JNIEnv指針的方式是不同的.
c>在這個(gè)文件里調(diào)用設(shè)備商提供的dll文件,設(shè)備商一般提供三種文件:dll/lib/h,這里假設(shè)分別為A.dll/A.lib/A.h.
這個(gè)地方的調(diào)用分為動(dòng)態(tài)調(diào)用和靜態(tài)調(diào)用靜態(tài)調(diào)用即是只要把被調(diào)用的dll文件放到path路徑下,然后加載lib鏈接文件和.h頭文件即可直接調(diào)用A.dll中的方法:
把設(shè)備商提供的A.h文件使用"Add Fiels to Project"菜單加載到這個(gè)工程中,同時(shí)在源代碼文件中要把這個(gè)A.h文件使用include包含進(jìn)來(lái);
然后依次點(diǎn)擊"Project->settings"菜單,打開(kāi)link選項(xiàng)卡,把A.lib添加到"Object/library modules"選項(xiàng)中.
具體的代碼如下:
//讀出數(shù)據(jù),需要注意的是如果是c程序在調(diào)用JNI函數(shù)時(shí)必須在JNIEnv的變量名前加*,如(*env)->xxx,如果是c++程序,則直接使用(env)->xxx

#include<WINDOWS.H>
#include<MALLOC.H>
#include<STDIO.H>
#include<jni.h>
#include "test_LinkDll.h"
#include "A.h"

JNIEXPORT jstring JNICALL Java_test_LinkDll_readDataTemp( JNIEnv *env, jobject jo, jint ji_icdev, jint ji_len )
{
    //*************************基本數(shù)據(jù)聲明與定義******************************
     HANDLE H_icdev = (HANDLE)ji_icdev;//設(shè)備標(biāo)志符
    __int16 i16_len = (__int16)ji_len;//讀出的數(shù)據(jù)長(zhǎng)度,值為3,即3個(gè)HEX形式的字符
    __int16 i16_result;//函數(shù)返回值
    __int16 i16_coverResult;//字符轉(zhuǎn)換函數(shù)的返回值
        int i_temp;//用于循環(huán)的中間變量
      jchar jca_result[3] = { 'e', 'r', 'r' };//當(dāng)讀數(shù)據(jù)錯(cuò)誤時(shí)返回此字符串

    //無(wú)符號(hào)字符指針,指向的內(nèi)存空間用于存放讀出的HEX形式的數(shù)據(jù)字符串
    unsigned char* uncp_hex_passward = (unsigned char*)malloc( i16_len );
    //無(wú)符號(hào)字符指針,指向的內(nèi)存空間存放從HEX形式轉(zhuǎn)換為ASC形式的數(shù)據(jù)字符串
    unsigned char* uncp_asc_passward = (unsigned char*)malloc( i16_len * 2 );
    //java char指針,指向的內(nèi)存空間存放從存放ASC形式數(shù)據(jù)字符串空間讀出的數(shù)據(jù)字符串
    jchar *jcp_data = (jchar*)malloc(i16_len*2+1);
    //java String,存放從java char數(shù)組生成的String字符串,并返回給調(diào)用者
    jstring js_data = 0;

    //*********讀出3個(gè)HEX形式的數(shù)據(jù)字符到uncp_hex_data指定的內(nèi)存空間**********
    i16_result = readData( H_icdev, 6, uncp_hex_data );//這里直接調(diào)用的是設(shè)備商提供的原型方法.

    if ( i16_result != 0 )
    {
        printf( "讀卡錯(cuò)誤......\n" );
        //這個(gè)地方調(diào)用JNI定義的方法NewString(jchar*,jint),把jchar字符串轉(zhuǎn)換為JString類型數(shù)據(jù),返回到j(luò)ava程序中即是String
        return (env)->NewString( jca_result, 3 );
    }

    printf( "讀數(shù)據(jù)成功......\n" );

    //**************HEX形式的數(shù)據(jù)字符串轉(zhuǎn)換為ASC形式的數(shù)據(jù)字符串**************
    i16_coverResult = hex_asc( uncp_hex_data, uncp_asc_data, 3 );
    if ( i16_coverResult != 0 )
    {
        printf( "字符轉(zhuǎn)換錯(cuò)誤!\n" );
        return (env)->NewString( jca_result, 3 );
    }

    //**********ASC char形式的數(shù)據(jù)字符串轉(zhuǎn)換為jchar形式的數(shù)據(jù)字符串***********
    for ( i_temp = 0; i_temp < i16_len; i_temp++ ) 
        jcp_data[i_temp] = uncp_hex_data[i_temp];
    //******************jchar形式的數(shù)據(jù)字符串轉(zhuǎn)換為java String****************
    js_data = (env)->NewString(jcp_data,i16_len); 
    return js_data;
}

動(dòng)態(tài)調(diào)用,不需要lib文件,直接加載A.dll文件,并把其中的文件再次聲明,代碼如下:
#include<STDIO.H>
#include<WINDOWS.H>
#include "test_LinkDll.h"

//首先聲明一個(gè)臨時(shí)方法,這個(gè)方法名可以隨意定義,但參數(shù)同設(shè)備商提供的原型方法的參數(shù)保持一致.
typedef int ( *readDataTemp )( int, int, int, unsigned char * );//從指定地址讀數(shù)據(jù)

//從指定地址讀數(shù)據(jù)
JNIEXPORT jstring JNICALL Java_readDataTemp( JNIEnv *env, jobject jo, jint ji_icdev, jint ji_offset, jint ji_len )
{
    int i_temp;
    int i_result;
    int i_icdev = (int)ji_icdev;
    int i_offset = (int)ji_offset;
    int i_len = (int)ji_len;
    jchar jca_result[5] = { 'e', 'r', 'r' };
    unsigned char *uncp_data = (unsigned char*)malloc(i_len);
    jchar *jcp_data = (jchar *)malloc(i_len);
    jstring js_data = 0;
    //HINSTANCE是win32中同HANDLE類似的一種數(shù)據(jù)類型,意為Handle to an instance,常用來(lái)標(biāo)記App實(shí)例,在這個(gè)地方首先把A.dll加載到內(nèi)存空間,以一個(gè)App的形式存放,然后取

得它的instance交給dllhandle,以備其它資源使用.
    HINSTANCE dllhandle;
    dllhandle = LoadLibrary( "A.dll" );
    //這個(gè)地方首先定義一個(gè)已聲明過(guò)的臨時(shí)方法,此臨時(shí)方法相當(dāng)于一個(gè)結(jié)構(gòu)體,它和設(shè)備商提供的原型方法具有相同的參數(shù)結(jié)構(gòu),可互相轉(zhuǎn)換
    readDataTemp readData;

    //使用win32的GetProcAddress方法取得A.dll中定義的名為readData的方法,并把這個(gè)方法轉(zhuǎn)換為已被定義好的同結(jié)構(gòu)的臨時(shí)方法,
    //然后在下面的程序中,就可以使用這個(gè)臨時(shí)方法了,使用這個(gè)臨時(shí)方法在這時(shí)等同于使用A.dll中的原型方法.
    readData = (readDataTemp) GetProcAddress( dllhandle, "readData" );

    i_result = (*readData)( i_icdev, i_offset, i_len, uncp_data );

    if ( i_result != 0 )
    {
        printf( "讀數(shù)據(jù)失敗......\n" );
        return (env)->NewString( jca_result, 3 );
    }

    for ( i_temp = 0; i_temp < i_len; i_temp++ )
    {
        jcp_data[i_temp] = uncp_data[i_temp];
    }

    js_data = (env)->NewString( jcp_data, i_len );

    return js_data;
}

4>以上即是一個(gè)java程序調(diào)用第三方dll文件的完整過(guò)程,當(dāng)然,在整個(gè)過(guò)程的工作全部完成以后,就可以使用java類LinkDll中的public String radData( int, int, int )方法了,效果同直接使用c/c++調(diào)用這個(gè)設(shè)備商提供的A.dll文件中的readData方法幾乎一樣.

總結(jié):JNI技術(shù)確實(shí)是提高了java程序的執(zhí)行效率,并且擴(kuò)展了java程序的功能,但它也確確實(shí)實(shí)破壞了java程序的最重要的優(yōu)點(diǎn):平臺(tái)無(wú)關(guān)性,所以除非必須(不得不)使用JNI技術(shù),一般還是提倡寫100%純java的程序.根據(jù)自己的經(jīng)驗(yàn)及查閱的一些資料,把可以使用JNI技術(shù)的情況羅列如下:
    1>需要直接操作物理設(shè)備,而沒(méi)有相關(guān)的驅(qū)動(dòng)程序,這時(shí)候我們可能需要用C甚至匯編語(yǔ)言來(lái)編寫該設(shè)備的驅(qū)動(dòng),然后通過(guò)JNI調(diào)用;
    2>涉及大量數(shù)學(xué)運(yùn)算的部分,用java會(huì)帶來(lái)些效率上的損失;
    3>用java會(huì)產(chǎn)生系統(tǒng)難以支付的開(kāi)銷,如需要大量網(wǎng)絡(luò)鏈接的場(chǎng)合;
    4>存在大量可重用的c/c++代碼,通過(guò)JNI可以減少開(kāi)發(fā)工作量,避免重復(fù)開(kāi)發(fā).
另外,在利用JNI技術(shù)的時(shí)候要注意以下幾點(diǎn):
    1>由于Java安全機(jī)制的限制,不要試圖通過(guò)Jar文件的方式發(fā)布包含本地化方法的Applet到客戶端;
    2>注意內(nèi)存管理問(wèn)題,雖然在本地方法返回Java后將自動(dòng)釋放局部引用,但過(guò)多的局部引用將使虛擬機(jī)在執(zhí)行本地方法時(shí)耗盡內(nèi)存;
    3>JNI技術(shù)不僅可以讓java程序調(diào)用c/c++代碼,也可以讓c/c++代碼調(diào)用java代碼.

注:有一個(gè)名叫Jawin開(kāi)源項(xiàng)目實(shí)現(xiàn)了直接讀取第三方dll文件,不用自己辛苦去手寫一個(gè)起傳值轉(zhuǎn)換作用的dll文件,有興趣的可以研究一下.但是我用的時(shí)候不太順手,有很多規(guī)則限制,像自己寫程序時(shí)可以隨意定義返回值,隨意轉(zhuǎn)換類型,用這個(gè)包的話這些都是不可能的了,所以我的項(xiàng)目還沒(méi)開(kāi)始就把它拋棄了.



無(wú)很 2011-07-28 12:37 發(fā)表評(píng)論
]]>
J2EE 13種技術(shù)規(guī)范http://www.aygfsteel.com/wuhen86/articles/355211.html無(wú)很無(wú)很Thu, 28 Jul 2011 04:34:00 GMThttp://www.aygfsteel.com/wuhen86/articles/355211.htmlhttp://www.aygfsteel.com/wuhen86/comments/355211.htmlhttp://www.aygfsteel.com/wuhen86/articles/355211.html#Feedback0http://www.aygfsteel.com/wuhen86/comments/commentRss/355211.htmlhttp://www.aygfsteel.com/wuhen86/services/trackbacks/355211.htmlJ2EE平臺(tái)由一整套服務(wù)(Services)、應(yīng)用程序接口(APIs)和協(xié)議構(gòu)成,它對(duì)開(kāi)發(fā)基于Web的多層應(yīng)用提供了功能支持,下面對(duì)J2EE中的13種技術(shù)規(guī)范進(jìn)行簡(jiǎn)單的描述(限于篇幅,這里只能進(jìn)行簡(jiǎn)單的描述):
1.JDBC(Java Database Connectivity):
JDBC API為訪問(wèn)不同的數(shù)據(jù)庫(kù)提供了一種統(tǒng)一的途徑,象ODBC一樣,JDBC對(duì)開(kāi)發(fā)者屏蔽了一些細(xì)節(jié)問(wèn)題,另外,JDCB對(duì)數(shù)據(jù)庫(kù)的訪問(wèn)也具有平臺(tái)無(wú)關(guān)性。
2.JNDI(Java Name and Directory Interface):
JNDI API被用于執(zhí)行名字和目錄服務(wù)。它提供了一致的模型來(lái)存取和操作企業(yè)級(jí)的資源如DNS和LDAP,本地文件系統(tǒng),或應(yīng)用服務(wù)器中的對(duì)象。
3.EJB(Enterprise JavaBean):
J2EE技術(shù)之所以贏得某體廣泛重視的原因之一就是EJB。它們提供了一個(gè)框架來(lái)開(kāi)發(fā)和實(shí)施分布式商務(wù)邏輯,由此很顯著地簡(jiǎn)化了具有可伸縮性和高度復(fù)雜的企業(yè)級(jí)應(yīng)用的開(kāi)發(fā)。EJB規(guī)范定義了EJB組件在何時(shí)如何與它們的容器進(jìn)行交互作用。容器負(fù)責(zé)提供公用的服務(wù),例如目錄服務(wù)、事務(wù)管理、安全性、資源緩沖池以及容錯(cuò)性。但這里值得注意的是,EJB并不是實(shí)現(xiàn)J2EE的唯一途徑。正是由于J2EE的開(kāi)放性,使得有的廠商能夠以一種和EJB平行的方式來(lái)達(dá)到同樣的目的。
4.RMI(Remote Method Invoke):
正如其名字所表示的那樣,RMI協(xié)議調(diào)用遠(yuǎn)程對(duì)象上方法。它使用了序列化方式在客戶端和服務(wù)器端傳遞數(shù)據(jù)。RMI是一種被EJB使用的更底層的協(xié)議。
5.Java IDL/CORBA:
在Java IDL的支持下,開(kāi)發(fā)人員可以將Java和CORBA集成在一起。 他們可以創(chuàng)建Java對(duì)象并使之可在CORBA ORB中展開(kāi), 或者他們還可以創(chuàng)建Java類并作為和其它ORB一起展開(kāi)的CORBA對(duì)象的客戶。后一種方法提供了另外一種途徑,通過(guò)它Java可以被用于將你的新的應(yīng)用和舊的系統(tǒng)相集成。
6.JSP(Java Server Pages):
JSP頁(yè)面由HTML代碼和嵌入其中的Java代碼所組成。服務(wù)器在頁(yè)面被客戶端所請(qǐng)求以后對(duì)這些Java代碼進(jìn)行處理,然后將生成的HTML頁(yè)面返回給客戶端的瀏覽器。
7.Java Servlet:
Servlet是一種小型的Java程序,它擴(kuò)展了Web服務(wù)器的功能。作為一種服務(wù)器端的應(yīng)用,當(dāng)被請(qǐng)求時(shí)開(kāi)始執(zhí)行,這和CGI Perl腳本很相似。Servlet提供的功能大多與JSP類似,不過(guò)實(shí)現(xiàn)的方式不同。JSP通常是大多數(shù)HTML代碼中嵌入少量的Java代碼,而servlets全部由Java寫成并且生成HTML。
8.XML(Extensible Markup Language):
XML是一種可以用來(lái)定義其它標(biāo)記語(yǔ)言的語(yǔ)言。它被用來(lái)在不同的商務(wù)過(guò)程中共享數(shù)據(jù)。XML的發(fā)展和Java是相互獨(dú)立的,但是,它和Java具有的相同目標(biāo)正是平臺(tái)獨(dú)立性。通過(guò)將Java和XML的組合,您可以得到一個(gè)完美的具有平臺(tái)獨(dú)立性的解決方案。
9.JMS(Java Message Service):
MS是用于和面向消息的中間件相互通信的應(yīng)用程序接口(API)。它既支持點(diǎn)對(duì)點(diǎn)的域,有支持發(fā)布/訂閱(publish/subscribe)類型的域,并且提供對(duì)下列類型的支持:經(jīng)認(rèn)可的消息傳遞,事務(wù)型消息的傳遞,一致性消息和具有持久性的訂閱者支持。JMS還提供了另一種方式來(lái)對(duì)您的應(yīng)用與舊的后臺(tái)系統(tǒng)相集成。
10.JTA(Java Transaction Architecture):
JTA定義了一種標(biāo)準(zhǔn)的API,應(yīng)用系統(tǒng)由此可以訪問(wèn)各種事務(wù)監(jiān)控。
11.JTS(Java Transaction Service):
JTS是CORBA OTS事務(wù)監(jiān)控的基本的實(shí)現(xiàn)。JTS規(guī)定了事務(wù)管理器的實(shí)現(xiàn)方式。該事務(wù)管理器是在高層支持Java Transaction API (JTA)規(guī)范,并且在較底層實(shí)現(xiàn)OMG OTS specification的Java映像。JTS事務(wù)管理器為應(yīng)用服務(wù)器、資源管理器、獨(dú)立的應(yīng)用以及通信資源管理器提供了事務(wù)服務(wù)。
12.JavaMail:
JavaMail是用于存取郵件服務(wù)器的API,它提供了一套郵件服務(wù)器的抽象類。不僅支持SMTP服務(wù)器,也支持IMAP服務(wù)器。
13.JAF(JavaBeans Activation Framework):
JavaMail利用JAF來(lái)處理MIME編碼的郵件附件。MIME的字節(jié)流可以被轉(zhuǎn)換成Java對(duì)象,或者轉(zhuǎn)換自Java對(duì)象。大多數(shù)應(yīng)用都可以不需要直接使用JAF。

 

轉(zhuǎn)自:http://hi.baidu.com/dinguangx/blog/item/c6f5003ddcd688c19e3d6279.html



無(wú)很 2011-07-28 12:34 發(fā)表評(píng)論
]]>
pl/sql中添加 shortcuts插件http://www.aygfsteel.com/wuhen86/articles/355188.html無(wú)很無(wú)很Thu, 28 Jul 2011 01:05:00 GMThttp://www.aygfsteel.com/wuhen86/articles/355188.htmlhttp://www.aygfsteel.com/wuhen86/comments/355188.htmlhttp://www.aygfsteel.com/wuhen86/articles/355188.html#Feedback0http://www.aygfsteel.com/wuhen86/comments/commentRss/355188.htmlhttp://www.aygfsteel.com/wuhen86/services/trackbacks/355188.html在pl/sql中添加快捷鍵的支持只需要把一個(gè)文本類型的文件plugin.txt放入到pl/sql安裝目錄下的plugins文件夾中。

其中plugin.txt 文件中的內(nèi)容為(自定義的內(nèi)容,可以根據(jù)自己的習(xí)慣設(shè)置):

s = select * from
sc* = select count(*) from
w = where
ss = select /*+parallel(a,6)*/ * from

打開(kāi)pl/sql developer進(jìn)入[首選項(xiàng)]->[用戶界面]->[編輯器]->[autoreplace],選中enabled復(fù)選框,再查找 plugin.txt所在的路徑,點(diǎn)擊[應(yīng)用]即完成插件的安裝。

重啟pl/sql developer,打開(kāi)sql編輯窗口,輸入s,再按空格,就可以出現(xiàn)select * from,這樣就可以不必每次都輸入這段經(jīng)常使用而又經(jīng)常打錯(cuò)的語(yǔ)句了。



無(wú)很 2011-07-28 09:05 發(fā)表評(píng)論
]]>
myeclipse工程改為Eclipsehttp://www.aygfsteel.com/wuhen86/articles/351347.html無(wú)很無(wú)很Mon, 30 May 2011 08:33:00 GMThttp://www.aygfsteel.com/wuhen86/articles/351347.htmlhttp://www.aygfsteel.com/wuhen86/comments/351347.htmlhttp://www.aygfsteel.com/wuhen86/articles/351347.html#Feedback0http://www.aygfsteel.com/wuhen86/comments/commentRss/351347.htmlhttp://www.aygfsteel.com/wuhen86/services/trackbacks/351347.html中加入 org.eclipse.wst.common.project.facet.core.natureorg.eclipse.wst.common.modulecore.ModuleCoreNatureorg.eclipse.jem.workbench.JavaEMFNature中加入 org.eclipse.wst.common.project.facet.core.builderorg.eclipse.wst.validation.validationbuilder 做完以上步驟後,刷新項(xiàng)目;點(diǎn)擊右鍵->項(xiàng)目->右鍵 ->Properties->Project Facets->Modify Project在彈出的面板中,選擇Java和Dynamic Web Module 下一步是配置Context Root 和Content Directory 以及源碼路徑,配置完成。

無(wú)很 2011-05-30 16:33 發(fā)表評(píng)論
]]>
如何不重新啟動(dòng) Emacs 就讓 .emacs 的配置起作用http://www.aygfsteel.com/wuhen86/articles/350470.html無(wú)很無(wú)很Wed, 18 May 2011 05:53:00 GMThttp://www.aygfsteel.com/wuhen86/articles/350470.htmlhttp://www.aygfsteel.com/wuhen86/comments/350470.htmlhttp://www.aygfsteel.com/wuhen86/articles/350470.html#Feedback0http://www.aygfsteel.com/wuhen86/comments/commentRss/350470.htmlhttp://www.aygfsteel.com/wuhen86/services/trackbacks/350470.html我剛剛使用 Emacs 的時(shí)候,總是

vi ~/.emacs

然后重新啟動(dòng) emacs ,效率很低 ,暗自嘟囔, emacs 怎么沒(méi)有這種功能,不重起,就自動(dòng)更新 .emacs 的設(shè)置 呢?

后來(lái)我發(fā)現(xiàn),這個(gè)功能完全沒(méi)有必要,我的做法是:

  • 用 emacs 打開(kāi) .emacs 文件,C-x C-e 光標(biāo)前面的運(yùn)行一條語(yǔ)句。立即生效。
  • 選擇一個(gè) region , M-x eval-region
  • M-x load-file ~/.emacs
  • M-x eval-buffer

都是立即生效,可以馬上試驗(yàn)一條語(yǔ)句的效果。 例如,在任何一個(gè)文件中,寫

(setq frame-title-format "emacs@%b")

把光標(biāo)停在在這條語(yǔ)句后面, C-x C-e ,馬上看到 emacs 的 標(biāo)題欄上發(fā)生變化。

我用這種方法調(diào)試我的每一個(gè)小的配置文件,按上篇文章說(shuō)的方法, 把他放在 ~/Emacs/myconfig/my-site-start.d 中。

轉(zhuǎn)自:http://ann77.emacser.com/Emacs/EmacsDotEmacsWithoutRestart.html

Technorati : ,



無(wú)很 2011-05-18 13:53 發(fā)表評(píng)論
]]>
Emacs快捷鍵http://www.aygfsteel.com/wuhen86/articles/329476.html無(wú)很無(wú)很Fri, 20 Aug 2010 08:01:00 GMThttp://www.aygfsteel.com/wuhen86/articles/329476.htmlhttp://www.aygfsteel.com/wuhen86/comments/329476.htmlhttp://www.aygfsteel.com/wuhen86/articles/329476.html#Feedback0http://www.aygfsteel.com/wuhen86/comments/commentRss/329476.htmlhttp://www.aygfsteel.com/wuhen86/services/trackbacks/329476.html基本命令

C-x C-c : 退出Emacs

C-x C-f : 打開(kāi)一個(gè)文件,如果文件不存在,則創(chuàng)建一個(gè)文件

C-g : 取消未完成的命令

編輯

C-z (redefined): Undo;原來(lái)C-z是掛起Emacs(然后用fg命令調(diào)出);C-x u 是默認(rèn)的命令; 移動(dòng)一下光標(biāo),再C-z就可以redo

M-d : 刪除光標(biāo)后的詞語(yǔ)

移動(dòng)光標(biāo)

C-v : 向前翻頁(yè)

M-v : 向后翻頁(yè)

M-r : 將光標(biāo)移動(dòng)到屏幕中間那行

C-a : 移到行首

M-a : 移到句首,從行首到句首之間可能有空格

C-e : 移到行尾

M-e : 移到句尾

M-{ : 向上移動(dòng)一段

M-} : 向下移動(dòng)一段

C-right : 向前移動(dòng)一個(gè)單詞

C-left : 向后移動(dòng)一個(gè)單詞

C-up : 向前移動(dòng)一段

C-down : 向后移動(dòng)一段

M-< : 移到整個(gè)文本開(kāi)頭

M-> : 移到整個(gè)文本末尾

C-u 數(shù)字 命令 : 執(zhí)行多次(數(shù)字表示次數(shù))該命令;“M-數(shù)字 命令” 也可以

M-x goto-line : 移動(dòng)到某一行

C-l : 重繪屏幕,效果就是當(dāng)前編輯行移動(dòng)窗口中央

Buffer 相關(guān)

C-x k : 關(guān)閉當(dāng)前buffer

C-x b : 切換到前一個(gè)編輯的buffer

C-x C-b : 列出當(dāng)前所有buffer

C-x C-s : 保存當(dāng)前buffer

C-x s : 保存所有未保存的buffer,會(huì)提示你是否需要保存

C-x C-w : 文件另存為

拷貝與粘貼

M-space (redefined): 設(shè)置mark; C-@ 是默認(rèn)命令

C-w (redefined) : 剪切一塊區(qū)域;如果沒(méi)有設(shè)置mark,則是剪切一行

M-w (redefined) : 拷貝一塊區(qū)域;如果沒(méi)有設(shè)置mark, 則是拷貝一行

C-k : 從當(dāng)前位置剪切到行尾

C-y : 粘貼

M-y : 用C-y拉回最近被除去的文本后,換成 M-y可以拉回以前被除去的文本。鍵入多次的M-y可以拉回更早以前被除去的文本。

C-x r k : 執(zhí)行矩形區(qū)域的剪切

C-x r y : 執(zhí)行矩形區(qū)域的粘貼

窗口操作

C-x 0 : 關(guān)閉當(dāng)前窗口

C-x 1 : 將當(dāng)前窗口最大化

C-x 2 : 垂直分割窗口

C-x 3 : 水平分割窗口

M-o (redefined) : 在窗口之間切換; C-x o 是默認(rèn)命令

C-x 5 1/2/3/0 : 對(duì)frame類似的操作

C-x < : 窗口內(nèi)容右卷

C-x > : 窗口內(nèi)容左卷(這兩個(gè)命令在垂直分割窗口后比較有用)

(C-u) C-x ^ : 加高當(dāng)前窗口,如果有C-u,則每次加高4行

(C-u) C-x } : 加寬當(dāng)前窗口

(C-u) C-x { : 壓窄當(dāng)前窗口

ESC C-v : 在其它窗口進(jìn)行卷屏操作

搜索和替換

C-s : 向前搜索(增量式搜索);連續(xù)C-s,跳到下一個(gè)搜索到的目標(biāo)

C-s RET : 普通搜索

C-r : 向前搜索

C-s RET C-w : 按單詞查詢

M-% : 查詢替換,也就是替換前會(huì)詢問(wèn)一下

M-x replace-string : 普通替換

Tags

M-! etags .c .h : 創(chuàng)建TAGS文件

M-. : 跳到tag所在位置

M-x list-tags : 列出tags

Bookmark

C-x r m : 設(shè)置書簽bookmark

C-x r b : 跳到bookmark處

幫助

C-h ? : 查看幫助信息

C-h f : 查看一個(gè)函數(shù)

C-h v : 查看一個(gè)變量

C-h k : 查看一個(gè)鍵綁定 (C-h(huán) c 也是查看鍵綁定,但是信息較簡(jiǎn)略)

C-h C-f : 查看一個(gè)函數(shù)的Info,非常有用

C-h i : 看Info

其它

C-M-\ : 對(duì)選中區(qū)域,按照某種格式(比如C程序)進(jìn)行格式化

C-x h : 全部選中

M-! : 執(zhí)行外部shell命令

M-x shell : 模擬shell的buffer

M-x term : 模擬terminal, C-c k 關(guān)閉terminal

C-x C-q : 修改buffer的只讀屬性

翻頁(yè)
C-v 下一頁(yè)
M-v 上一頁(yè)
選擇
M-h     選擇段落
C-x h   全部選擇
普通區(qū)塊
C-SPC   M-x set-mark-command 單個(gè)位置set mark
C-@     同上
M-@     對(duì)word進(jìn)行set Mark
M-w     先set Mark,移到光標(biāo),M-w就可以復(fù)制
C-w     剪切
矩形區(qū)塊
用這些快捷鍵要先關(guān)閉cua-mode
C-x r t      用串填充矩形區(qū)域
C-x r o      插入空白的矩形區(qū)域
C-x r y      插入之前刪除的矩形區(qū)域, 粘貼時(shí),矩形左上角對(duì)齊光標(biāo)
C-x r k      刪除矩形區(qū)域
C-x r c      將當(dāng)前矩形區(qū)域清空
寄存器
----------------------------------------------------------------------
光標(biāo)位置和窗口狀態(tài)
C-x r SPC <寄存器名>                   存貯光標(biāo)位置
C-x r w <寄存器名>                     保存當(dāng)前窗口狀態(tài)
C-x r f <寄存器名>                     保存所有窗口狀態(tài)
C-x r j <寄存器名>                     光標(biāo)跳轉(zhuǎn)
文本和數(shù)字
C-x r s <寄存器名>                     將連續(xù)區(qū)塊拷貝到寄存器中
C-x r r <寄存器名>                     將矩形區(qū)塊拷貝到寄存器中
C-u <數(shù)字> C-x r n <寄存器名>           將數(shù)字拷貝到寄存器中
C-x r i <寄存器名>                     在緩沖區(qū)中插入寄存器內(nèi)容
M-x view-register                     查看寄存器內(nèi)容
M-x list-registers                    查看寄存器列表
宏模式
C-x (                    開(kāi)始一個(gè)宏的定義
C-x )                    結(jié)束一個(gè)宏的定義
C-x e                    執(zhí)行宏
M-x name-last-kbd-macro  給最后一個(gè)宏命名
M-x insert-kbd-macro     在當(dāng)前文件中插入一個(gè)已定義并命名過(guò)的宏
書簽
C-x r m <name>           設(shè)置書簽
C-x r b <name>           跳轉(zhuǎn)到書簽
C-x r l                  書簽列表
M-x bookmark-delete      刪除書簽
M-x bookmark-load        讀取存儲(chǔ)書簽文件
M-x bookmark-save        保存到文件
目錄模式
----------------------------------------------------------------------
C-x d     M-x dired     啟動(dòng)目錄模式
C-x C-d   簡(jiǎn)單目錄

 

程序
C-x C-z 掛起程序
C-c C-x 退出程序
C-c k   關(guān)閉buffer
C-l     重畫屏幕
C-g     結(jié)束命令,或者假死中恢復(fù),也可以按3次ESC
文件
C-x C-s 保存
C-x C-w 另存為
C-x C-f 打開(kāi)文件
C-x C-r 只讀方式打開(kāi)
C-x C-v 讀入另外一個(gè)文件代替當(dāng)前buffer的文件
C-x s   保存所有
C-x i   將文件的內(nèi)容插入
M-x revert-buffer    恢復(fù)到原始狀態(tài)
跳轉(zhuǎn)
前/后     單位
C-f/b    字
M-f/b    詞
C-a/e    行內(nèi)
M-a/e    句
M-</>    文檔
C-p/n    行間
M-{/}    段落
C-x ]/[  頁(yè)
C-x C-x  文件內(nèi),mark之間
M-g g  跳到指定行
M-x goto-char 跳到指定字符
編輯
M-u       后面單詞變?yōu)榇髮?
M-l       后面單詞變?yōu)樾?
M-c       后面單詞的首字母變大寫
M-/       補(bǔ)全
C-j       從當(dāng)前位置分成兩行,相當(dāng)于RET + tab
M-(       插入()
C-q tab   插入tab
C-q C-m   插入^M
M-;       插入注釋
C-o       回車
刪除
M-d   后一詞
C-d   后一字
M-del 前一詞
M-k   到句尾
M-"   前面的所有空白
M-z   刪到指定字母處
C-k   刪除到行尾
文本換位
C-t        字符
M-t        單詞
C-x C-t    行
M-x transpose-* 其他命令
撤銷
C-/
C-x u
C-_
C-z
重做
C-g M-x undo
C-g C-/
C-g C-z
C-g C-_
粘貼
C-y
C-v
tab/空格轉(zhuǎn)換
M-x tabify
M-x untabify
讓選擇的區(qū)塊自動(dòng)對(duì)齊
M-x indent-region
其他命令
C-u <數(shù)字> <命令> 重復(fù)命令n次
M-<數(shù)字>   <命令> 同上
M-!     運(yùn)行shell命令
C-u M-! 執(zhí)行一條外部命令,并輸出到光標(biāo)位置
M-x cd  改變工作目錄
M-x pwd 當(dāng)前工作目錄
C-" 啟動(dòng)輸入法
M-` 菜單
F10 菜單
M-x eval-buffer 在.emacs的buffer中運(yùn)行,重新加載emacs配置
查找替換
----------------------------------------------------------------------
C-r 向上查找
C-s 向下查找
C-s C-w 向下查找,光標(biāo)位置的單詞作為查找字符串
C-s C-y 向下查找,光標(biāo)位置到行尾作為查找字符串
C-s RET <查找字符串> RET   非遞增查找
C-s RET C-w              不受換行、空格、標(biāo)點(diǎn)影響
C-M-s                    正則式向下查找
用向上查找命令就將上面命令的s替換為r
M-%   替換
C-M-% 正則式替換
y 替換當(dāng)前的字符串并移動(dòng)到下一個(gè)字符串
n 不替換當(dāng)前字符串,直接移動(dòng)到下一個(gè)字符串
! 進(jìn)行全局替換,并要求不再顯示
. 替換當(dāng)前字符串,然后退出查找替換操作
q 退出查找替換操作,光標(biāo)定位到操作開(kāi)始時(shí)的位置
其他命令
M-x replace-*
M-x search-*
窗口
C-x 0 關(guān)掉當(dāng)前窗口
C-x 1 關(guān)掉其他窗口
C-x o 切換窗口
C-x 2 水平兩分窗口
C-x 3 垂直兩分窗口
C-x 5 2 新frame
buffer
C-x C-b        查看
C-x b          切換
C-x C-q        設(shè)為只讀
C-x k          刪除
C-x left/right 切換



無(wú)很 2010-08-20 16:01 發(fā)表評(píng)論
]]>
JSF2.0初探http://www.aygfsteel.com/wuhen86/articles/325634.html無(wú)很無(wú)很Fri, 09 Jul 2010 04:51:00 GMThttp://www.aygfsteel.com/wuhen86/articles/325634.htmlhttp://www.aygfsteel.com/wuhen86/comments/325634.htmlhttp://www.aygfsteel.com/wuhen86/articles/325634.html#Feedback2http://www.aygfsteel.com/wuhen86/comments/commentRss/325634.htmlhttp://www.aygfsteel.com/wuhen86/services/trackbacks/325634.html一直想研究Java JSF,上網(wǎng)找了下,遺憾的是國(guó)內(nèi)JSF的資料少的可憐.于是上網(wǎng)找了參考點(diǎn)資料,去官方網(wǎng)站下載了JSF的開(kāi)發(fā)包.廢話少說(shuō),看配置.

一,配置JSF

把JSF2.0內(nèi)的兩個(gè)開(kāi)發(fā)包jsf-api.jar,jsf-impl.jar拷貝到Eclipse項(xiàng)目的lib目錄中(建立web項(xiàng)目略). 在web.xml中添加以下內(nèi)容:

<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>

<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>

<context-param>
<param-name>com.sun.faces.resourceUpdateCheckPeriod</param-name>
<param-value>-1</param-value>
</context-param>

<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.do</url-pattern> <!--此處名字可以隨便起,可以是*.action,*.faces 等 我習(xí)慣用*.do-->
</servlet-mapping>

這樣jsf框架已經(jīng)添加進(jìn)項(xiàng)目中了.接下來(lái)就要建立Bean了.如下所示:

package com.joy.jsf.beans;

//@ManagedBean(name="users") jsf2.0可以不用配置文件來(lái)管理bean
public class User {

private String userName;
private String userPassword;
private String errorMessage;

public String getErrorMessage() {
return errorMessage;
}

public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public String getUserPassword() {
return userPassword;
}

public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}

public String Check() {
if (!this.userName.equals("JOY") || !this.userPassword.equals("123456")) {
this.errorMessage = "名稱或密碼錯(cuò)誤";
return "failure";
} else {
return "success";
}
}
}

之后要定制導(dǎo)航規(guī)則,新建face-config.xml 如下所示:

<faces-config>
<!-- <application>
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
</application> -->
<navigation-rule>
<from-view-id>/index.jsp</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/pages/welcome.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>failure</from-outcome>
<to-view-id>/index.jsp</to-view-id>
</navigation-case>
</navigation-rule>

<!--<managed-bean> <managed-bean-name>users</managed-bean-name> <managed-bean-class>
com.joy.jsf.beans.User </managed-bean-class> <managed-bean-scope>request</managed-bean-scope>
</managed-bean> -->
</faces-config>

配置文件建立完了,添加view頁(yè)面. index.jsp和welcome.jsp

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="f" uri=">
<%@ taglib prefix="h" uri="
>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>首頁(yè)</title>
</head>
<body>
<f:view>
<h:form>
姓名:<h:inputText value="#{users.userName }" /><br/>
密碼:<h:inputText value="#{users.userPassword }"></h:inputText><br/>
<h:commandButton value="submit" action="#{users.Check}"></h:commandButton>
<br/>
<h:outputText value="#{users.errorMessage}"/><p>

</h:form>
</f:view>
</body>
</html>

welcome.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="f" uri="
>
<%@ taglib prefix="h" uri="
>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>歡迎回來(lái)</title>
</head>
<body>
<f:view>
<h:form>
Hello <h:outputText value="#{users.userName }"></h:outputText> ,Welcome to here!

</h:form>
</f:view>
</body>
</html>

保存,部署,運(yùn)行http://localhost:8080/JSF/index.do

二,整合Spring

添加spring開(kāi)發(fā)包,spring.jar,stadard.jar,commons-logging.jar,jstl.jar

web.xml 添加如下配置

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
<description>添加Srping支持</description>
<display-name>Spring</display-name>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

然后在face-config.xml中添加

<application>
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
</application>

從spring工廠中獲取bean ,如果和jsf的托管bean一起使用,則托管bean的優(yōu)先級(jí)要高于spring.

添加applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=" xmlns:xsi="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx

<bean id="users" class="com.joy.jsf.beans.User">

</bean>
</beans>

重新部署,運(yùn)行.

OK.



無(wú)很 2010-07-09 12:51 發(fā)表評(píng)論
]]>
主站蜘蛛池模板: 星子县| 文登市| 万年县| 桐柏县| 商城县| 晋中市| 太康县| 静海县| 繁峙县| 莎车县| 土默特左旗| 外汇| 兴宁市| 乌鲁木齐市| 兴隆县| 潮州市| 汤阴县| 永福县| 南乐县| 保靖县| 宁化县| 大同市| 泾川县| 石门县| 山西省| 河源市| 朝阳县| 岳池县| 临沂市| 西和县| 连城县| 永德县| 富锦市| 德令哈市| 将乐县| 东莞市| 绥芬河市| 贵阳市| 乐东| 西乌| 永春县|