日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java高新技术笔记:反射、多线程、泛型、枚举、javaBean、代理

發(fā)布時(shí)間:2024/2/28 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java高新技术笔记:反射、多线程、泛型、枚举、javaBean、代理 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.


1、IDE: Integrated Development Environment

2、集成開發(fā)環(huán)境兩個(gè)主流:Eclipse和netBeans

3、preference: 偏愛

4、Compiler: 編譯器;

5.Switcha javaspace:切換Java工作間

6.Perspective:透視圖

7.雖然我一直用Eclipse的alt加反斜杠,但是不知道它的英文名字,在preference中的key-contentAssist內(nèi)容協(xié)助選項(xiàng)來(lái)設(shè)置一下快捷鍵

8、Myeclipse中的調(diào)試debug,可以使用step up 進(jìn)行下一行,要查看變量的話右擊變量選中watch,下一行就會(huì)看到變量的變化了。

9、Java模版template:定義自己的快捷鍵:

10、jdk1.6新特性,可變參數(shù)

11、ariableParameter :可變參數(shù)

這個(gè)是JDK5.0以上的版本新加的功能。那個(gè)for循環(huán)也是新加的功能。那個(gè)可變參數(shù)的就是個(gè)數(shù)組,你傳多少個(gè)參數(shù)都被放到那個(gè)數(shù)組里面。 這樣方便了程序員,因?yàn)槿绻淮_定要傳的參數(shù)的個(gè)數(shù)的話,我們要寫帶1個(gè)參數(shù)的,帶2個(gè)參數(shù),帶3個(gè)參數(shù)的,這樣很麻煩。? 該進(jìn)后的這個(gè)方法,我們只要寫一個(gè)函數(shù)就好,可以傳任意個(gè)參數(shù)

可變參數(shù)的數(shù)組args,是不包含第一個(gè)參數(shù)的哦,這個(gè)要記住。

package com.jianjian;

//jdk1.5 新特性,可變參數(shù)

public class Test2

{

?? public static void main(String[] args)

?? {

????? System.out.println(method(2,3,4));

????? System.out.println(method(3,4,5,5,6));

?? }

??

?? public static int method (int a ,int...args)

?? {

????? int sum = a;

????? System.out.println(args[0]);

????? for(int i = 0; i < args.length; i ++)

????? {

??????? sum = sum + args[i];

????? }

????? return sum;

?? }

}

?

?

10.

在導(dǎo)入包的時(shí)候一定要注意統(tǒng)一編碼!以及jdk的版本統(tǒng)一

11、

享元模式:flyWeight

12、享元模式(英語(yǔ):Flyweight Pattern)是一種軟件設(shè)計(jì)模式。它使用共享物件,用來(lái)盡可能減少內(nèi)存使用量以及分享資訊給盡可能多的相似物件;它適合用于當(dāng)大量物件只是重復(fù)因而導(dǎo)致無(wú)法令人接受的使用大量?jī)?nèi)存。通常物件中的部分狀態(tài)是可以分享。常見做法是把它們放在外部數(shù)據(jù)結(jié)構(gòu),當(dāng)需要使用時(shí)再將它們傳遞給享元。

典型的享元模式的例子為文書處理器中以圖形結(jié)構(gòu)來(lái)表示字符。一個(gè)做法是,每個(gè)字形有其字型外觀, 字模 metrics, 和其它格式資訊,但這會(huì)使每個(gè)字符就耗用上千字節(jié)。取而代之的是,每個(gè)字符參照到一個(gè)共享字形物件,此物件會(huì)被其它有共同特質(zhì)的字符所分享;只有每個(gè)字符(文件中或頁(yè)面中)的位置才需要另外儲(chǔ)存。以下程式用來(lái)解釋上述的文件例子。這個(gè)例子用來(lái)解釋享元模式利用只載立執(zhí)行立即小任務(wù)所必需的資料,因而減少內(nèi)存使用量。  

?

?

13、Java反射機(jī)制

JAVA反射機(jī)制:“程序運(yùn)行時(shí),允許改變程序結(jié)構(gòu)或變量類型,這種語(yǔ)言稱為動(dòng)態(tài)語(yǔ)言”。從這個(gè)觀點(diǎn)看,Perl,Python,Ruby是動(dòng)態(tài)語(yǔ)言,C++,Java,C#不是動(dòng)態(tài)語(yǔ)言。但是JAVA有著一個(gè)非常突出的動(dòng)態(tài)相關(guān)機(jī)制:Reflection,用在Java身上指的是我們可以于運(yùn)行時(shí)加載、探知、使用編譯期間完全未知的classes。換句話說(shuō),Java程序可以加載一個(gè)運(yùn)行時(shí)才得知名稱的class,獲悉其完整構(gòu)造(但不包括methods定義),并生成其對(duì)象實(shí)體、或?qū)ζ鋐ields設(shè)值、或喚起其methods

?

14.Class對(duì)象沒有構(gòu)造方法,所以不能new出對(duì)象來(lái)

15、Class c =Person.class//這是一個(gè)字節(jié)碼,這個(gè)類的字節(jié)碼就會(huì)從內(nèi)存中加載進(jìn)來(lái)

16.Class.forName()返回一個(gè)字節(jié)碼

17、有三種方法獲得對(duì)象的字節(jié)碼

package com.jianjian;

?

public class Test3

{

?? public static void main(String[] args)throws ClassNotFoundException

?? {

????? Class c = Test3.class;

????? System.out.println(c);

????? System.out.println(c.getClass());

????? System.out.println(Class.forName("java.lang.String"));

?? }

}

?

?

18、

八中基本數(shù)據(jù)類型,加上void.class

19.

三種方法是用來(lái)返回字節(jié)碼所對(duì)應(yīng)的類,這是唯一的;

package com.jianjian;

?

public class Test3

{

?? public static void main(String[] args)throws ClassNotFoundException

?? {

????? String s = "hello";

????? Class s1 = s.getClass();

????? Class s2 = String.class ;

????? Class s3 = Class.forName("java.lang.String");

????? //這三種方法返回的字節(jié)碼對(duì)應(yīng)于同意類,所以字節(jié)碼是相同的

????? System.out.println(s3);

?????

????? System.out.println(s1== s2);

????? System.out.println(s1 == s3);

?? }

}

返回的都是同一類的字節(jié)碼

?

?

19.

Class的isPremitiv()方法,將判斷返回的字節(jié)碼是不是基本類型,包裝類型的TYPE屬性,將返對(duì)應(yīng)基本類型的字節(jié)碼:

也就是說(shuō)int.Class == Integer.TYPE;

20、這個(gè)方法同樣可以驗(yàn)證數(shù)組也是對(duì)象,比如說(shuō)

int[].class.isPrimitive()就將返回false,說(shuō)明整形數(shù)組并不是基本數(shù)據(jù)類型哦,void也是一個(gè)類型,因?yàn)橛兴鼈兏髯缘腸lass對(duì)象

?

23. package com.jianjian;

?

import java.lang.reflect.Constructor;

import java.util.Arrays;

?

public class Test5

{

?? public static void main(String[] args)throws ClassNotFoundException

?? {

????? Class c = Class.forName("java.lang.String");

????? System.out.println(c);

????? Constructor[] s = c.getConstructors();

????? System.out.println(Arrays.toString(s));//獲取所有的構(gòu)造方法

?

?? }

}

23/

?

24.

反射比較占用性能,導(dǎo)致程序性能嚴(yán)重下降

25、

Fileled類:反射中的成員變量

26.關(guān)于重寫和hashset的快捷鍵在Eclipse中是alt+shift+s

?

?

28.

字節(jié)碼一定要用等號(hào)比;因?yàn)槎际悄猛环?/p>

29、

反射這個(gè)東西是無(wú)論如何也要弄懂啊:

反射中的Filed類,可以用于反射提取類中的成員變量:

我覺得例如Method類Constructor類都因該有類似的功能,

Class類中有兩個(gè)用來(lái)提取成員變量的方法,一個(gè)是

getField(Stringname);

一個(gè)是

getFields()

對(duì)于第一個(gè)是用來(lái)接受指定類中的一個(gè) 成員變量,傳入的字符串就是成員變量定義時(shí)的名字;但是要記住的是返回的類型是Field類,下面要用get方法傳入具體的對(duì)象才能獲得值;

比如說(shuō)是這樣的:

一個(gè)類中Test有兩個(gè)成員變量

privateint a ;

publicint b;

我用getField(“a”)將獲得成員變量a對(duì)應(yīng)的Field,但這只是類的成員變量,不是對(duì)象的成員變量,你打印的話,將會(huì)輸出類名加成員變量名,在用get方法傳入Test就能得到a的值;

?

而我用getFields()方法,將返回一個(gè)Field[] 數(shù)組,其中f[0]對(duì)應(yīng)a,f[1]對(duì)應(yīng)b;

然后就能分別進(jìn)行處理;

但是 有注意到,b是私有的成員變量,這在反射中是不可見的,用getField方法將不能取得私有的成員變量,只有使用getDeclaredFiled(Sting name)getDeclaredFields()方法了;當(dāng)然得到的類的私有成員變量也不能被訪問(wèn),需要暴力反射;獲取訪問(wèn)權(quán)限;使用setAccessible(true)之后,再用get方法取出:

下面是完整的代碼:

?

package com.jianjian;

?

import java.lang.reflect.Field;

import java.util.Arrays;

?

public class Test1

{

?? public static void main(String[] args)throws Exception

?

?? {

????? Test2 test = new Test2(3,5);

????? Class c = test.getClass();//獲得類對(duì)應(yīng)的字節(jié)碼,這是反射的第一步;

????? //首先使用getField()方法輸出成員變量

????? Field f1 = c.getField("a");

????? Field f2 = c.getDeclaredField("b");//因?yàn)?/span>b是私有的成員變量

????? int a = (Integer)f1.get(test);//get方法返回的是Object類型的

????? f2.setAccessible(true);//允許對(duì)私有成員變量訪問(wèn);

????? int b = (Integer)f2.get(test);

????? System.out.println(a);

????? System.out.println(b);

?????

?????

????? //下面使用getFields()方法輸出成員變量

????? Field[] f = c.getDeclaredFields();//因?yàn)橛兴接械某蓡T變量,所以最好建議都是用這個(gè)方法

????? System.out.println(f[0].get(test));//省去匹配的步驟

????? f[1].setAccessible(true);

????? System.out.println(f[1].get(test));

?????

?????

?????

?????

?????

?? }

}

?

?

?

?

?

?

?

3.

package com.jianjian;

?

public class Test2

{

?? public int a ;

?? public int b;

?? public Strings1 ="basketball";//注意只有public的才可以使用getFields,其他的請(qǐng)用declared

?? public Strings2 ="ball";

??

?? public Test2(int a ,int b)

?? {

????? this.a = a;

????? this.b = b;

?? }

?? //打印對(duì)象就是打印對(duì)象的toSting方法,現(xiàn)在重寫一下對(duì)象的toString方法,

?? //讓它打印s1s2

?? public String toString()

?? {

????? return s1 +";"+ s2;

?? }

??

??

}

?

?

package com.jianjian;

?

import java.lang.reflect.Field;

?

public class Test3

{

?? /*反射的高級(jí)應(yīng)用,竊取篡改信息

?? ?* 用反射來(lái)獲取Test2中的字符串變量,這就要求有篩選的步驟

?? ?* 獲取變涼后將字符串中的字符a變成字符b;在輸出字符串;

?? ?*/

??

?? public static void main(String[] args)throws Exception

?? {

????? Test2 test = new Test2(3,5);

????? Class c = test .getClass();

????? //首先篩出所有的成員變量

????? Field[] f = c.getFields();

????? for(Field? field : f)

????? {

??????? if(field.getType() == String.class)//判斷這個(gè)成員變量是不是字符串,字節(jié)碼一定要用

??????? {

?????????? String str = (String)field.get(test);//返回的對(duì)象肯定是字符串

?????????? //提取并更改字符串ab

?????????? String newStr = str.replace('b','a');

?????????? System.out.println(newStr);

?????????? field.set(test,newStr);//將新的局部變量加入到原有的對(duì)象中

???????

??????? }

???????

???????

????? }

????? System.out.println(test);

?????

?????

?????

?????

?????

?????

?????

?????

?????

?????

?????

?????

?????

?? }

}

30.

用發(fā)射調(diào)用方法:比如說(shuō)調(diào)用String中的charAt(int index)

方法,這個(gè)用反射怎么實(shí)現(xiàn):

Class類中的getMethod(Stringname, Class papameter)方法接受兩個(gè)參數(shù),一個(gè)是要反射的方法名字,第二個(gè)是方法名字所接受數(shù)據(jù)類型的字節(jié)碼,這是個(gè)可變參數(shù)(variable Parameter)

就是為了區(qū)分方法重載,確定你要調(diào)用那一個(gè)方法;

package com.jianjian;

?

import java.lang.reflect.Method;

?

public class Test4

{

?? public static void main(String[] args)throws Exception

?? {

????? String s = "helloWorld";

?

????? Class c = s.getClass();

????? Method method = c.getMethod("charAt",int.class);

????? char a = (Character) method.invoke(s, 0);//沒有人知道一個(gè)類中的某一個(gè)方法到底返回什么類型,只要你知道

????? System.out.println(a);

?

?? }

}

31、

package com.jianjian;

//普通的調(diào)用一個(gè)類的main方法

public class Test8

{

?? public static void main(String[] args)

?? {

?

????? Reflect.main(new String[] {"1","222" });

?? }

}

?

class Reflect

{

?? public static void main(String[] args)

?? {

????? for (String s : args)

????? {

??????? System.out.println(s);

????? }

?? }

?

}

?

?

32、

選中一個(gè)類然后按下F2就可以看到這個(gè)類的完整類名了;

package com.jianjian;

?

public class Test9

{

?? public static void main(String[] args)

?? {

????? for(String s :args)

????? {

??????? System.out.println(s);

????? }

?? }

}

?

package com.jianjian;

//用反射的方式來(lái)調(diào)用test9中的main方法

import java.lang.reflect.Method;

?

public class Test8

{

?? public static void main(String[] args)throws Exception

?? {

????? //首先,我要獲得Test9中的完整類路徑名;需要為args賦值的話,請(qǐng)用

????? //f2獲得當(dāng)前類的的完整路徑名,然后run as,運(yùn)行配置,在當(dāng)前的main方法中將類名賦予第一個(gè)參數(shù)

????? String className = args[0];//這樣就獲得了Test9的類名稱

????? Class c = Class.forName(className);

????? Method m = c.getDeclaredMethod("main", String[].class);//是一個(gè)字符串?dāng)?shù)組類的字節(jié)碼

?

????? System.out.println(m);

????? m.invoke(null, (Object)new String[] {"222","333","444" });

????? //這個(gè)Object最好記住,就是把數(shù)組當(dāng)成整體,因?yàn)閷?shí)際上args本身也就是一個(gè),如果不加Object這就相當(dāng)于是三個(gè)了

?????

?????

?? }

}

?

?

33.

/*

?* 看張老師的視屏還是收獲頗豐啊!

?* int類型是基本數(shù)據(jù)類型,不是對(duì)象類型,不繼承Object

?* Java中所有的數(shù)組都是對(duì)象,也就是說(shuō)數(shù)組也是繼承了Object

?* 所以我可以這樣說(shuō),int[]繼承了Object

?* 下面再來(lái)看一下int[] Object[]的區(qū)別

?* int[]的意思是定義一個(gè)整形數(shù)組,里面存放int型的基本數(shù)據(jù)

?* Object[]的意思是定義一個(gè)Object類型的數(shù)組,里面存放Object類型的對(duì)象,

?* 一個(gè)放基本數(shù)據(jù)類型,一個(gè)放對(duì)象類型,你說(shuō)相等不想等

?* 所以有 Object[] b == Integer[] a;Object[] == int[]這個(gè)是絕對(duì)錯(cuò)的;

?* 但是Object[] b是不是可以等于 int[][] a呢;答案是肯定的,int[][]可以這樣來(lái)理解,

?* 定義一個(gè)int類型的數(shù)組,里面用來(lái)存放int類型的數(shù)組,兩個(gè)都是Object類型的,肯定是相等的,

?* 所以以后不要再把對(duì)象類型強(qiáng)制為對(duì)象類型了!,看下面的例子!

?*/

package com.jianjian;

?

public class Test10

{

?? public static void main(String[] args)

?? {

????? int[] a1 = new int[10];

????? int[][] a2 =newint[2][3];

????? String[] s = new String[3];

????? Object[] o = new Object[10];

????? // o = a1;這行是錯(cuò)的

????? o = a2;

????? o = s;

????? s = (String[]) o;

?

?? }

}

?

?

34.

?

判斷是不是數(shù)組Arrays.isArray();

?

?

35/

?

?

36/

相對(duì)路徑和絕對(duì)路徑

絕對(duì)路徑:是從盤符開始的路徑,形如 C:\windows\system32\cmd.exe 相對(duì)路徑:是從當(dāng)前路徑開始的路徑,假如當(dāng)前路徑為C:\windows 要描述上述路徑,只需輸入 system32\cmd.exe 實(shí)際上,嚴(yán)格的相對(duì)路徑寫法應(yīng)為 .\system32\cmd.exe 其中,.表示當(dāng)前路徑,在通道情況下可以省略,只有在特殊的情況下不能省略。 假如當(dāng)前路徑為c:\program files 要調(diào)用上述命令,則需要輸入 ..\windows\system32\cmd.exe 其中,..為父目錄。 當(dāng)前路徑如果為c:\program files\common files 則需要輸入 ..\..\windows\system32\cmd.exe另外,還有一種不包含盤符的特殊絕對(duì)路徑,形如 \windows\system32\cmd.exe 無(wú)論當(dāng)前路徑是什么,會(huì)自動(dòng)地從當(dāng)前盤的根目錄開始查找指定的程序。

introspector

37、

?

?

38、不是太理解javabean的作用

?

?

39.

來(lái)說(shuō)一下我自己對(duì)javaBean的理解吧,如果說(shuō),我想從一個(gè)類中,拿取它的成員變量,當(dāng)然,我不知道這個(gè)成員變量的訪問(wèn)修飾符是怎樣的,只知道里面有一個(gè)獲取該變量的方法,比如說(shuō)get方法,但是我又不知道其他人是怎么定義的這個(gè)方法名字,javabean就可以從傳入的對(duì)象類中,獲取這個(gè)類似的get方法和set方法:

package com.jianjian;

?

import java.beans.PropertyDescriptor;

import java.lang.reflect.Method;

?

public class Test12

{

?? public static void main(String[] args)throws Exception

?? {

????? Test11 test = new Test11(22,"zhangsan");

????? String varName = "age";//定義要獲取的變量的名稱

????? PropertyDescriptor pro1 = new PropertyDescriptor(varName, test

?????????? .getClass());

????? // 可以看到,PropertyDescriptorbean包下的一個(gè)類,它的構(gòu)造方法,接收兩個(gè)參數(shù),一個(gè)

????? // 你要獲取的變量的名字,第二個(gè)是對(duì)象類的字節(jié)碼

?

????? Method getMethod = pro1.getReadMethod();

????? // 意思是獲取對(duì)象中的一個(gè)可以讀取變量的一個(gè)方法,同樣的有write方法

????? // 獲取方法后當(dāng)然就可以使用invoke來(lái)調(diào)用了

????? Object ob = getMethod.invoke(test);

????? System.out.println(ob);//然后你就可以看到22

?

????? // 下面我來(lái)將原有對(duì)象中的name屬性修改,該位33

?

????? Method setMethod = pro1.getWriteMethod();//獲取set類似方法

????? setMethod.invoke(test, 33);

????? Object ob2 = getMethod.invoke(test);

????? System.out.println(ob2);

?

?? }

}

一個(gè)Eclipse小技巧:方法重構(gòu):Method

當(dāng)然,其實(shí)上面的代碼只完成了兩件事,一個(gè)是獲取一個(gè)整形的變量name,一個(gè)是set一個(gè)整形的變量name進(jìn)去,這完全也可以用兩個(gè)方法來(lái)實(shí)現(xiàn)

方法重構(gòu):Method Refactor:alt + shift + t

?

對(duì)選中的代碼重組成一個(gè)方法,最好不要出現(xiàn)基本類型,最好將變量卸載外部,能夠用來(lái)調(diào)用也就是傳遞進(jìn)方法:

package com.jianjian;

?

import java.beans.PropertyDescriptor;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

?

public class Test12

{

?? public static void main(String[] args)throws Exception

?? {

????? Test11 test = new Test11(22,"zhangsan");

????? String varName = "age";//定義要獲取的變量的名稱

????? PropertyDescriptor pro1 = new PropertyDescriptor(varName,test.getClass());

????? // 可以看到,PropertyDescriptorbean包下的一個(gè)類,它的構(gòu)造方法,接收兩個(gè)參數(shù),一個(gè)

????? // 你要獲取的變量的名字,第二個(gè)是對(duì)象類的字節(jié)碼

?

????? Method getMethod = pro1.getReadMethod();

????? // 意思是獲取對(duì)象中的一個(gè)可以讀取變量的一個(gè)方法,同樣的有write方法

????? // 獲取方法后當(dāng)然就可以使用invoke來(lái)調(diào)用了

????? Object ob = getMethod.invoke(test);

????? System.out.println(ob);//然后你就可以看到22

?

????? // 下面我來(lái)將原有對(duì)象中的name屬性修改,該位33

?

????? retrunSet(test, pro1, getMethod);

?

?? }

?

?? private static void retrunSet(Test11 test, PropertyDescriptor pro1,

??????? Method getMethod) throws IllegalAccessException,

??????? InvocationTargetException

?? {

????? Method setMethod = pro1.getWriteMethod();//獲取set類似方法

????? setMethod.invoke(test, 33);

????? Object ob2 = getMethod.invoke(test);

????? System.out.println(ob2);

?? }

}

?


41.

對(duì)一個(gè)類中的一個(gè)變量名進(jìn)行更改,將會(huì)牽涉到所有的變量,選中變量名后,使用重構(gòu),或者用快捷方式 alt shift R

42/

這個(gè)意思是說(shuō)

package com.jianjian;

?

import java.util.ArrayList;

?

public class GenericTest1

{

?? public static void main(String[] args)

?? {

?? ArrayList<String> list1 = new ArrayList<String>();

?? ArrayList<Integer> list2 = new ArrayList<Integer>();

??

?? boolean b = (list1.getClass() == list2.getClass());

?? System.out.println(b);

?? }

}

你覺得打印的結(jié)果是true還是false呢,結(jié)果是true

?

43、

泛型是編譯期的行為,也就是說(shuō)只在編譯時(shí)起作用,如果你為集合添加的數(shù)據(jù)類型不匹配,它是會(huì)提醒你出錯(cuò)的,但是

反射是運(yùn)行期的,也就是說(shuō)它可以繞過(guò)泛型的約束,比如你可以向一個(gè)指定Integer類型的ArrayList添加一個(gè)字符串,下面用反射的方式來(lái)實(shí)現(xiàn):

package com.jianjian;

?

import java.util.ArrayList;

?

public class GenericTest2

{

?? public static void main(String[] args)throws Exception

?? {

????? ArrayList<Integer> list1 = new ArrayList<Integer>();

?????

????? //用反射的方法調(diào)用其add方法,添加一個(gè)字符串

????? list1.getClass().getMethod("add",Object.class).invoke(list1,"name");

????? System.out.println(list1.get(0));

?????

?????

?? }

}

結(jié)果證明真的是打印了name;

43、

?

?

?

?

44.

八種基本數(shù)據(jù)類型的父類是Number,所以用泛型的時(shí)候可以這樣寫:? extends Number

45、

?

46、

為自己掙了四個(gè)技術(shù)分的題目

package com.jianjian;

import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.util.ArrayList;

import java.util.Collections;

import java.util.Comparator;

import java.util.Iterator;

import java.util.List;

import java.util.Map;

import java.util.Set;

import java.util.TreeMap;

import java.util.Map.Entry;

?

public class Test {

?

?? /**

?? ?* 題目:已有字符串Str1,"sdfghellozxsdfcvwaadfafsasdfxcvdf"鍵盤輸入任意字符串,:String

?? ?*str2="HaHahello01", 在原來(lái)字符串Str1中去掉str2中最大的交集字符串(hello),

?? ?* 獲取該字符串str1中的每個(gè)字母出現(xiàn)的次數(shù)。

?? ?*

?? ?* 例如:去掉hello以這種方式打印:按次數(shù)從大到小排序,次數(shù)相同,按字母從大到小排序!

?? ?* f(出現(xiàn)6)d(出現(xiàn)5)s(出現(xiàn)4)x(出現(xiàn)2)v(出現(xiàn)2)c(出現(xiàn)2)w(出現(xiàn)1)g(出現(xiàn)1)

?? ?*

?? ?* @param args

?? ?* @throws Exception

?? ?* @author張熙韜

?? ?*/

?? public static void main(String[] args)throws Exception {

????? String str1 = "sdfg,hellozx,sdfcv-waadfa,fsasdfxcvdf";

????? BufferedReader bufr = new BufferedReader(new InputStreamReader(

??????? ?? System.in));

?

????? String str2 = bufr.readLine();

????? StringBuffer sb = new StringBuffer(str1);

?

????? // 去掉子字符串

????? int index = sb.indexOf(str2);

????? sb = sb.delete(index, index + str2.length());

?

????? String answer = sb.toString();

????? System.out.println("去掉最大子字符串之后的字符串為:" + answer);

?

????? // 統(tǒng)計(jì)每個(gè)字母出現(xiàn)的次數(shù)

????? StringBuffer answerSb = new StringBuffer(charCount(answer));

????? //System.out.println(answerSb.reverse());

????? System.out.println(answerSb);

?

?? }

?? /**

?? ?* 統(tǒng)計(jì)每個(gè)字母出現(xiàn)的次數(shù)

?? ?*

?? ?* @param str

?? ?* @return

?? ?*/

?? public static String charCount(String str) {

????? char[] chs = str.toCharArray();

????? // 傳入工具類反轉(zhuǎn)函數(shù),下面再定義EntryComparator函數(shù),最后排序結(jié)果是EntryComparator,說(shuō)明自定義函數(shù)優(yōu)先權(quán)最高!

????? TreeMap<Character, Integer> tm = newTreeMap<Character, Integer>(

?????????? Collections.reverseOrder());

????? for (int i = 0; i < chs.length; i++) {

??????? if (!(chs[i] >'a' && chs[i] <'z' || chs[i] >'A' && chs[i] <'Z')) {

?????????? continue;

??????? }

??????? Integer value = tm.get(chs[i]);

??????? if (value ==null) {

?????????? tm.put(chs[i], 1);

??????? } else {

?????????? value += 1;

?????????? tm.put(chs[i], value);

??????? }

????? }

????? StringBuilder sb = new StringBuilder();

????? Set<Map.Entry<Character, Integer>> entrySet =tm.entrySet();

?

????? //使用自定義子字符串進(jìn)行排序,先要將entrySet變成list集合,才能使用Collections.sort方法

????? List<Map.Entry<Character, Integer>> entryLists = newArrayList<Map.Entry<Character, Integer>>(entrySet);

?????

????? //使用Collections.sort方法對(duì)字符出現(xiàn)次數(shù)排序

????? Collections.sort(entryLists, new EntryComparator());

?????

????? Iterator<Entry<Character, Integer>>it=entryLists.iterator();

????? while(it.hasNext()){

??????? Entry<Character, Integer> me=it.next();

??????? Character key = me.getKey();

??????? Integer value = me.getValue();

??????? sb.append(key + "(出現(xiàn)" + value +")");

????? }

?????

????? //這種方式要簡(jiǎn)便一些

/*??? for (Entry<Character, Integer> entry : entryLists) {

??????? Character key = entry.getKey();

??????? Integer value = entry.getValue();

??????? sb.append(key + "(出現(xiàn)" + value + ")");

????? }*/

?

????? return sb.toString();

?? }

?

?? /**

?? ?* 獲取最大子字符串

?? ?*/

?? public static String getMaxString(String str1, String str2) {

????? String max = str1.length() > str2.length() ? str1 : str2;

????? String min = max == str1 ? str2 : str1;

????? for (int i = 0; i < min.length(); i++) {

??????? for (int j = 0, k = min.length() - i; k != min.length() + 1; j++,k++) {

?????????? String subString = min.substring(j, k);

?????????? if (max.contains(subString)) {

????????????? return subString;

?????????? }

????? ?? }

????? }

????? return null;

?? }

?

}

?

class EntryComparatorimplementsComparator<Map.Entry<Character, Integer>> {// value列表順序的比較器

?

?? public int compare(Map.Entry<Character, Integer> map1,

??????? Map.Entry<Character, Integer> map2) {//重寫compare方法

????? return map2.getValue().compareTo(map1.getValue());//降序排列

?? }

?

}

?

?

?

47.

Entry是一個(gè)接口,是Map的一個(gè)內(nèi)部類

java.util.Map.Entry

Entry相當(dāng)于是獨(dú)立的Map,單獨(dú)的存儲(chǔ)key set

map的entrySet方法返回一個(gè)set類型

entrySet

public Set<Map.Entry<K,V>> entrySet()

?

還記得兩種遍歷 map的方法嗎?

記住map本身并沒有實(shí)現(xiàn)Iterator接口哦!

package com.jianjian;

?

import java.util.HashMap;

import java.util.Iterator;

import java.util.Set;

import java.util.Map.Entry;

?

public class GenericTest3

{

?? public static void main(String[] args)

?? {

????? HashMap<String, Integer> map = new HashMap<String,Integer>();

????? map.put("zhangsan", 33);

????? map.put("lisi", 44);

????? map.put("wangwu", 55);

????? // Entry方法遍歷map成員

?

????? Set<Entry<String, Integer>> set = map.entrySet();//

????? for (Entry entry : set)

????? {

??????? System.out.println(entry.getKey());//得到key

??????? System.out.println(entry.getValue());//得到value

??????? ;

????? }

?

????? // 第二種方法,使用迭代器

????? Set<String> keySet = map.keySet();

?

????? for (Iterator<String> ite = keySet.iterator();ite.hasNext();)

????? {

??????? String name = ite.next();

??????? int age = map.get(name);

??????? System.out.println(name +":" + age);

?

????? }

?

?? }

}

?

?

48、

?

?

48、

49、

類加載器:Class loader

?

package com.jianjian;

?

public class ClassLoaderTest1

{

?? public static void main(String[] args)

?? {

????? Class c = ClassLoaderTest1.class.getClassLoader().getClass();

????? String name = c.getName();

????? System.out.println(c);//除了bootstrap是虛擬機(jī)加載器,其他的加載器都是Java類,都存在字節(jié)碼

?????

????? //來(lái)看一下bootStrap類加載器,通過(guò)System返回的是null,不代表不存在,而是存在于虛擬機(jī)中,無(wú)法被調(diào)用

?????

//??? Class c2 = System.class.getClassLoader().getClass();

//??? System.out.println(c2);

//??? 這樣打印出異常了,因?yàn)?/span>getClassLoaer的返回值是null

????? System.out.println(System.class.getClassLoader());

?????

?????

?? }

}

?

50.

?

?

?

51、

52、

package com.jianjian;

/*創(chuàng)建動(dòng)態(tài)類,及查看方法列表信息

?* StringBuilderStringBuffer的功能基本一致,知識(shí)在線程方面上有所區(qū)別

?* */

import java.lang.reflect.Constructor;

import java.lang.reflect.Proxy;

import java.util.Collection;

?

public class ProxyTest1

{

?? public static void main(String[] args)

?? {

????? //Proxy代理類的構(gòu)造方法接受兩個(gè)參數(shù),第一個(gè)參數(shù)是類加載器,第二個(gè)是接口的字節(jié)碼,以Collector為例

?? ?? Class clazzProxy =Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class);

????? //既然返回的是一個(gè)字節(jié)碼,那它肯定是一個(gè)類,下面打印它的構(gòu)造方法和方法

????? Constructor[] clazzConstructor =clazzProxy.getConstructors();

????? for(Constructor con : clazzConstructor)

????? {

??????? String name = con.getName();

??????? System.out.println(name);

??????? //這將會(huì)打印出構(gòu)造方法的名字,我想打印出構(gòu)造方法和其中的參數(shù)類型,來(lái)看一下字符串拼接

??????? StringBuilder str =new StringBuilder(name);

??????? str.append("(");

??????? //取出構(gòu)造方法中的參數(shù)

??????? Class[] clazzcon =?con.getParameterTypes();

??????? //前提是有參數(shù)

??????? if(clazzcon.length != 0)

??????? {

?????????? for(Class clazz: clazzcon)

?????????? {

????????????? str.append(clazz.getName());

????????????? str.append(",");

?????????? }

??????? }

??????? str.append(")");

??????? System.out.println(str.toString());

????????????????????????

???????

??????????

??????????

??????????

???????

???????

????? }

?????

?????

?? }

}

$Proxy0

$Proxy0(java.lang.reflect.InvocationHandler,)

?

54、

?

55、

代理類proxy的構(gòu)造方法要求接收一個(gè)InvocationHandle類型的參數(shù),而InvocationHandle是一接口,接口中只有一個(gè)方法: invoke,描述如下

Object

invoke(Object proxy,Method method,Object[] args)
Processes a method invocation on a proxy instance and returns the result.

?

要調(diào)用那個(gè)對(duì)象的那個(gè)方法的那些參數(shù)????

?

public static void main(String[] args)throws Exception

?? {

????? //Proxy代理類的構(gòu)造方法接受兩個(gè)參數(shù),第一個(gè)參數(shù)是類加載器,第二個(gè)是接口的字節(jié)碼,以Collector為例

????? Class clazzProxy = Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class);

????? //既然返回的是一個(gè)字節(jié)碼,那它肯定是一個(gè)類,下面打印它的構(gòu)造方法和方法

????? Constructor[]clazzConstructor = clazzProxy.getConstructors();

???????

????? Constructor con2 = clazzProxy.getConstructor(InvocationHandler.class);

????? //得到構(gòu)造方法

????? //得到代理類的實(shí)例:構(gòu)造方法接受一個(gè)InvocationHandle接口類型的參數(shù),使用匿名內(nèi)部累一步搞定

????? Object obj = con2.newInstance(new InvocationHandler(){

??????? @Override

??????? public Object invoke(Object proxy, Method method, Object[]args)

????????????? throws Throwable

??????? {

?????????? // TODO Auto-generatedmethod stub

?????????? return null;

??????? }

???????

???????

????? });

????? //這樣就用反射的方法得到了一個(gè)代理烈的實(shí)例對(duì)象,打印對(duì)象的toString方法

????? System.out.println(obj.toString());//打印的結(jié)果是null

????? //因?yàn)槟阍谀涿麅?nèi)部累中,什么都沒干,返回的是null

?????

?????

?

?

?

?

56、

但是這樣做還是有些麻煩,其實(shí)在Proxy類中提供了一個(gè)方法newProxyInstance

public static Object newProxyInstance(ClassLoader loader, ???????????????????????????????? ?????Class<?>[] interfaces, ????????????????????????????????????? InvocationHandler h) ???????????????????????? ??????throws IllegalArgumentException

?

這個(gè)方法將上面反射的步驟一步到位

1創(chuàng)建動(dòng)態(tài)類 2 得到動(dòng)態(tài)類的實(shí)例對(duì)象

可變參數(shù)只能位于參數(shù)的最后一個(gè),中間的只能是數(shù)組

package com.jianjian;

?

import java.lang.reflect.Constructor;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.util.Collection;

?

//下面我寫一下完整的,用反射的方法得到實(shí)現(xiàn)了Collection接口(可以多個(gè)接口)動(dòng)態(tài)類,并生成Collection動(dòng)態(tài)類的實(shí)例對(duì)象

public class ProxyTest2

{

?? public static void main(String[] args)throws Exception

?? {

????? //得到Collection動(dòng)態(tài)類

????? Class clazzCollection = Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class);

????? //生成Collection動(dòng)態(tài)類實(shí)例對(duì)象

????? //要接受的參數(shù)類型是InvocationHandle類型的參數(shù)

????? Constructor con = clazzCollection.getConstructor(InvocationHandler.class);

????? //生成實(shí)例對(duì)象,使用匿名內(nèi)部類

????? Object obj = con.newInstance(new InvocationHandler(){

???????

??????? @Override

??????? public Object invoke(Object proxy, Method method, Object[]args)

????????????? throws Throwable

??????? {

?????????? // TODO Auto-generatedmethod stub

?????????? return null;

??????? }

????? });

?????

????? //打印這個(gè)對(duì)象

????? System.out.println(obj.toString());

?????

?????

?????

?? }

}

?

然后是使用Proxy的newInstance()方法

public class ProxyTest3

{

?? public static void main(String[] args)

?? {

????? //注意到第二個(gè)參數(shù)的提示,是一個(gè)class[]數(shù)組,但是我只需要添加一個(gè)Collection類型的接口就可以了

????? //注意看一下怎么寫,new clss[]{Collection.class}

????? Collection collection =(Collection) Proxy.newProxyInstance(Collection.class.getClassLoader(),

?????????? ???? newClass[]{Collection.class},

?????????? ???? newInvocationHandler()

????????????? {

????????????????

???????????????? @Override

???????????????? public Object invoke(Object proxy, Method method, Object[]args)

????????????????????? throws Throwable

????????????? ?? {

??????????????????? // TODO Auto-generatedmethod stub

??????????????????? returnnull;

???????????????? }

????????????? }

????? );

?? }

}

?

?

56.

package com.jianjian;

?

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.util.ArrayList;

import java.util.Collection;

?

public class ProxyTest3

{

?? public static void main(String[] args)

?? {

????? // 注意到第二個(gè)參數(shù)的提示,是一個(gè)class[]數(shù)組,但是我只需要添加一個(gè)Collection類型的接口就可以了

????? // 注意看一下怎么寫,new clss[]{Collection.class}

????? Collection collection = (Collection) Proxy.newProxyInstance(

?????????? Collection.class.getClassLoader(),

?????????? new Class[] { Collection.class },new InvocationHandler()

?????????? {

????????????? ArrayList list =newArrayList();//這里打印2

?

????????????? @Override

????????????? public Object invoke(Object proxy, Method method,

??????????????????? Object[] args) throws Throwable

????????????? {

???????????????? // ArrayList list= new ArrayList();

???????????????? // list寫到成員變量里面,就不會(huì)初始化了,這里打印0

???????????????? // TODO Auto-generatedmethod stub

???????????????? return method.invoke(list, args);

????????????? }

?????????? });

?

????? // 得到實(shí)例對(duì)象之后,就可以調(diào)用對(duì)象的方法了;

????? // 打印一下未加參數(shù)時(shí)它的size方法

????? // System.out.println(collection.size());

????? // 結(jié)果是空指針異常,這說(shuō)明對(duì)象為空,因?yàn)槟憔蜎]有處理對(duì)象,返回的是null

????? // 下面,我們將對(duì)象指定為ArrayList

????? collection.add("zhangsan");//動(dòng)態(tài)類每使用一次就會(huì)去調(diào)用handler對(duì)象的invoke方法,這也就是實(shí)現(xiàn)了對(duì)原方法的改動(dòng)

?

????? collection.add("lisi");

????? System.out.println(collection.size());

?

?? }

}

?

?

?

?

?

?

?

?

?

57

Object

invoke(Object proxy,Method method,Object[] args)
Processes a method invocation on a proxy instance and returns the result.

這個(gè)方法接受的三個(gè)參數(shù)到底是什么呢?

代理對(duì)象,代理對(duì)象的那個(gè)方法,接受那些參數(shù)

我來(lái)演示一下代理的原理,本來(lái),執(zhí)行collection.add()方法時(shí),會(huì)調(diào)用handler的invoke方法,但是invoke指定的對(duì)象確實(shí)可變的,下面就是我把執(zhí)行的對(duì)象換成了ArrayList,最后返回的是ArrayList對(duì)象,這就是動(dòng)態(tài)類的改變功能,在方法的什么位置寫,用什么對(duì)象,都會(huì)產(chǎn)生差異,其實(shí)add方法的返回值就是invoke返回的對(duì)象Object,你可以生成驗(yàn)證

要注意到add方法已經(jīng)發(fā)生了改變了

new Class[] { Collection.class },new InvocationHandler()

?????????? {

????????????? ArrayList list =newArrayList();//這里打印2

?

????????????? @Override

????????????? public Object invoke(Object proxy, Method method,

??????????????????? Object[] args) throws Throwable

????????????? {

???????????????? Object obj = method.invoke(list,args);

????????????????

???????????????? // TODO Auto-generatedmethod stub

???????????????? return obj;

????????????? }

?????????? });

?

當(dāng)然也可以對(duì)參數(shù)進(jìn)行修改!

這也就是解釋了為什么調(diào)用 collection.add方法會(huì)出現(xiàn)異常,因?yàn)檎{(diào)用該方法,觸發(fā)invoke方法返回的對(duì)象是你自己指定的,我當(dāng)時(shí)返回的是null,null可不是整形啊,所以肯定會(huì)報(bào)錯(cuò)的

但是但是:不是對(duì)象的所有方法都交給Handler,比如說(shuō)調(diào)用Collection.getClass方法,這是因?yàn)槔^承了Object的類,getClass是Object的方法,看文檔

只有這三個(gè)方法會(huì)用到Invoke方法,其他的object的方法將會(huì)有自己的調(diào)用

58、

?


總結(jié)

以上是生活随笔為你收集整理的Java高新技术笔记:反射、多线程、泛型、枚举、javaBean、代理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。