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

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

生活随笔

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

java

java反射随意值_Java反射笔记

發(fā)布時(shí)間:2023/12/19 java 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java反射随意值_Java反射笔记 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Java反射

反射庫(kù)提供了一個(gè)豐富且精巧的工具集,可以用來(lái)編寫(xiě)能夠動(dòng)態(tài)操縱Java代碼的程序。能夠分析類能力的程序稱為反射(reflective)。反射機(jī)制的功能極為強(qiáng)大,反射機(jī)制可以用來(lái):

在運(yùn)行時(shí)分析類的能力

在運(yùn)行時(shí)檢查對(duì)象,例如,編寫(xiě)一個(gè)適用于所有類的toString方法

實(shí)現(xiàn)泛型數(shù)組操作代碼

利用Method對(duì)象

1、Class類

在程序運(yùn)行期間,Java運(yùn)行時(shí)系統(tǒng)始終為所有對(duì)象維護(hù)一個(gè)運(yùn)行時(shí)類型標(biāo)識(shí)。這個(gè)信息會(huì)跟蹤每個(gè)對(duì)象所屬的類。虛擬機(jī)利用運(yùn)行時(shí)類型信息選擇要執(zhí)行的正確的方法。

可以使用一個(gè)特殊的Java類訪問(wèn)這些信息。保存這些信息的類名為Class。

三種獲得Class類對(duì)象的方法:

class.getClass()

Class.forName(className)

class.class

虛擬機(jī)為每個(gè)類型管理一個(gè)唯一的Class對(duì)象。因此,可以使用==運(yùn)算符實(shí)現(xiàn)兩個(gè)類對(duì)象的比較。例如,

if(Employee.getClass()==Employee.class)//返回結(jié)果為true

如果有一個(gè)Class類型的對(duì)象,可以用它來(lái)構(gòu)造類的實(shí)例。調(diào)用getConstructor方法將得到一個(gè)Constructor類型的對(duì)象,然后使用newInstance方法來(lái)構(gòu)造一個(gè)實(shí)例。例如:

Class cl = Class.forName("java.util.Random");

Object obj = cl.getConstructor().newInstance;

如果這個(gè)類沒(méi)有無(wú)參數(shù)的構(gòu)造器,getConstructor方法會(huì)拋出一個(gè)異常。

API

java.lang.Class

static Class forName(String className)

返回一個(gè)Class對(duì)象,表示名為className的類

Constructor getConstructor(Class... paramterTypes)

生成一個(gè)對(duì)象,描述有指定參數(shù)類型的構(gòu)造器

java.lang.reflect.Constructor

Object newInstance(Object... params)

將params傳遞到構(gòu)造器,來(lái)構(gòu)造這個(gè)構(gòu)造器聲明類的一個(gè)新實(shí)例

2、資源

類通常有一些關(guān)聯(lián)的數(shù)據(jù)文件,例如

圖像和聲音文件

包含消息字符串和按鈕標(biāo)簽的文本文件。

Class類提供了一個(gè)很有用的服務(wù)可以查找資源文件。下面給出必要的步驟:

獲得擁有資源的類的Class對(duì)象,例如,ResourceTest.class

有些方法,如ImageIcon類的getImage方法,接受描述資源位置URL。則要調(diào)用

URL url = class.getResource("about.gif")

否則,使用getResourceAsStream方法得到一個(gè)輸入流來(lái)讀取文件中的數(shù)據(jù)

ResourceTest.java

/**

* 使用反射讀取資源

*/

public class ResourceTest {

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

Class cl = ResourceTest.class;

URL url = cl.getResource("about.jpg");

ImageIcon icon = new ImageIcon(url);

InputStream stream = cl.getResourceAsStream("about.txt");//相對(duì)路徑

byte[] bytes = new byte[1024];

stream.read(bytes);

String about = new String(bytes, "UTF-8");

InputStream stream2 = cl.getResourceAsStream("/com/company/reflection/about.txt");//絕對(duì)路徑

stream2.read(bytes);

String title = new String(bytes, StandardCharsets.UTF_8).trim();

JOptionPane.showMessageDialog(null,about,title,JOptionPane.INFORMATION_MESSAGE,icon);

}

}

API

java.lang.Class

URL getResource(String name)

InputStream getResourceAsStream(String name)

找到與類位于同一位置的資源,返回一個(gè)可以用來(lái)加載資源的URL或者輸入流。如果沒(méi)有找到資源,則返回null,所以不會(huì)拋出異常或者I/O錯(cuò)誤

3、利用反射分析類的能力

在java.lang.reflect包中有三個(gè)類Field、Method、Constructor分別用來(lái)描述類的字段、方法和構(gòu)造器。這三個(gè)類都有一個(gè)叫做getName的方法,用來(lái)返回字段、方法或構(gòu)造器的名稱。

Field類有一個(gè)getType方法,用來(lái)返回描述字段類型的一個(gè)對(duì)象,這個(gè)對(duì)象的類型同樣是Class。Method和Constructor類有報(bào)告參數(shù)類型的方法,Method類還有一個(gè)報(bào)告返回類型的方法。這三個(gè)類都有一個(gè)名為getModifiers的方法,它將返回一個(gè)整數(shù),用不同的0/1位描述所使用的修飾符,如public和static。另外,還可以利用java.lang.reflect包中的Modifier類的靜態(tài)方法分析getModifiers返回的這個(gè)整數(shù)。例如,可以使用Modifier類中的isPublic、isPrivate或isFinal判斷方法或構(gòu)造器是public、private還是final。我們需要做的就是在getModifiers返回的整數(shù)上調(diào)用Modifier類中適當(dāng)?shù)姆椒?#xff0c;另外,還可以利用Modifier.toString方法將修飾符打印出來(lái)。

ReflectionTest.java

/**

* 使用反射分析類的能力

*/

public class ReflectionTest {

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

String name;

if(args.length>0) name = args[0];

else

{

Scanner in = new Scanner(System.in);

System.out.println("Enter class name (e.g. java.util.Date): ");

name = in.next();

}

Class cl = Class.forName(name);//使用name獲取Class

Class supercl = cl.getSuperclass();//獲取父類的class

String modifiers = Modifier.toString(cl.getModifiers());//獲取修飾符

if(modifiers.length()>0) System.out.print(modifiers+" ");

System.out.print("class "+name);

if(supercl != null && supercl != Object.class) System.out.print(" extends "+supercl.getName());

System.out.print("\n{\n");

printConstructors(cl);

System.out.println();

printMethods(cl);

System.out.println();

printFields(cl);

System.out.println("}");

}

/**

* prints all constructors of a class

*/

public static void printConstructors(Class cl){

Constructor[] constructors = cl.getDeclaredConstructors();//獲取全部構(gòu)造器的數(shù)組

for(Constructor c : constructors){//遍歷構(gòu)造器數(shù)組

String name = c.getName();//獲取構(gòu)造器的name

System.out.print(" ");

String modifiers = Modifier.toString(c.getModifiers());//獲取構(gòu)造器的修飾符

if(modifiers.length()>0) System.out.print(modifiers+" ");

System.out.print(name+"(");

Class[] parameterTypes = c.getParameterTypes();//獲取構(gòu)造器的參數(shù)數(shù)組

for(int j = 0; j < parameterTypes.length; j++){//遍歷參數(shù)數(shù)組

if(j>0) System.out.print(", ");//逗號(hào)分隔開(kāi)

System.out.print(parameterTypes[j].getName());//打印參數(shù)name

}

System.out.println(");");

}

}

/**

* prints all methods of a class

*/

public static void printMethods(Class cl){

Method[] methods = cl.getDeclaredMethods();

for(Method m : methods){

Class> returnType = m.getReturnType();

String name = m.getName();

System.out.print(" ");

//print modifiers,return type and method name

String modifiers = Modifier.toString(m.getModifiers());

if(modifiers.length()>0) System.out.print(modifiers + " ");

System.out.print(returnType.getName() + " " + name + "(");

//print parameter types

Class[] parameterTypes = m.getParameterTypes();

for(int j = 0; j

if(j>0) System.out.print(", ");

System.out.print(parameterTypes[j].getName());

}

System.out.println(");");

}

}

/**

* prints all fields of a class

*/

public static void printFields(Class cl){

Field[] fields = cl.getDeclaredFields();

for(Field field : fields){

Class type = field.getType();

String name = field.getName();

System.out.print(" ");

String modifiers = Modifier.toString(field.getModifiers());

if(modifiers.length()>0) System.out.print(modifiers + " ");

System.out.println(type.getName() + " "+ name + ";");

}

}

}

輸入

java.lang.Double

輸出

public final class java.lang.Double extends java.lang.Number

{

public java.lang.Double(double);

public java.lang.Double(java.lang.String);

public boolean equals(java.lang.Object);

public static java.lang.String toString(double);

public java.lang.String toString();

public int hashCode();

public static int hashCode(double);

public static double min(double, double);

public static double max(double, double);

public static native long doubleToRawLongBits(double);

public static long doubleToLongBits(double);

public static native double longBitsToDouble(long);

public volatile int compareTo(java.lang.Object);

public int compareTo(java.lang.Double);

public byte byteValue();

public short shortValue();

public int intValue();

public long longValue();

public float floatValue();

public double doubleValue();

public static java.lang.Double valueOf(java.lang.String);

public static java.lang.Double valueOf(double);

public static java.lang.String toHexString(double);

public static int compare(double, double);

public static boolean isNaN(double);

public boolean isNaN();

public static boolean isFinite(double);

public static boolean isInfinite(double);

public boolean isInfinite();

public static double sum(double, double);

public static double parseDouble(java.lang.String);

public static final double POSITIVE_INFINITY;

public static final double NEGATIVE_INFINITY;

public static final double NaN;

public static final double MAX_VALUE;

public static final double MIN_NORMAL;

public static final double MIN_VALUE;

public static final int MAX_EXPONENT;

public static final int MIN_EXPONENT;

public static final int SIZE;

public static final int BYTES;

public static final java.lang.Class TYPE;

private final double value;

private static final long serialVersionUID;

}

API

java.lang.Class

Field[] getFields()

返回這個(gè)類支持的公共字段

Field[] getDeclaredFields()

返回類中聲明的全部字段

Method[] getMethods()

返回這個(gè)類支持的公共方法

Field[] getDeclaredMethods()

返回類中聲明的全部方法

Constructor[] getConstructors()

返回這個(gè)類支持的公共構(gòu)造器

Constructor[] getDeclaredConstructors()

返回類中聲明的全部構(gòu)造器

java.lang.reflect.Field

java.lang.reflect.Method

java.lang.reflect.Constructor

int getModifiers()

返回一個(gè)整數(shù),描述這個(gè)構(gòu)造器、方法或字段的修飾符。使用Modifier類中的方法來(lái)分析這個(gè)返回值

String getName()

返回一個(gè)表示構(gòu)造器名、方法名或字段名的字符串

Class[] getParamterTypes() (在Constructor 和 Method classes 類中)

返回一個(gè)Class對(duì)象數(shù)組,其中各個(gè)對(duì)象表示參數(shù)的類型。

Class getReturnType() (在 Method 類中)

返回一個(gè)用于表示返回類型的Class對(duì)象

java.lang.reflect.Modifier

static String toString(int modifiers)

返回一個(gè)字符串,包含對(duì)應(yīng)modifiers中位設(shè)置的修飾符

4、使用反射在運(yùn)行時(shí)分析對(duì)象

在編寫(xiě)程序時(shí),如果知道想要查看的字段名和類型,查看對(duì)象中指定字段的內(nèi)容是一件很容易的事情。而利用反射機(jī)制可以查看在編譯時(shí)還不知道的對(duì)象字段。

要做到這一點(diǎn),關(guān)鍵方法時(shí)Field類中的get方法。如果f是一個(gè)Field類型的對(duì)象,obj是某個(gè)包含f字段的類的對(duì)象,f.get(obj)將返回一個(gè)對(duì)象,其值為obj的當(dāng)前字段值。

ObjectAnalyzerTest.java

public class ObjectAnalyzerTest {

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

ArrayList squares = new ArrayList<>();

for (int i = 1; i <= 5; i++)

squares.add(i*i);

System.out.println(new ObjectAnalyzer().toString(squares));

}

}

ObjectAnalyzer.java

/**

* 使用反射在運(yùn)行時(shí)分析對(duì)象

*/

public class ObjectAnalyzer {

private ArrayList visted = new ArrayList<>();

/**

* 將對(duì)象轉(zhuǎn)換為列出所有字段的字符串表示形式

*/

public String toString(Object obj) throws IllegalAccessException {

if (obj == null) return null;

if (visted.contains(obj)) return "...";

visted.add(obj);

Class cl = obj.getClass();

if (cl == String.class) return (String)obj;

if (cl.isArray()){

String r = cl.getComponentType() + "[]{";// cl.getComponentType:返回表示數(shù)組的元素類型的Class

for (int i = 0; i< Array.getLength(obj); i++){

if (i > 0) r += ",";

Object val = Array.get(obj, i);

if (cl.getComponentType().isPrimitive()) r += val;// 如果是基本類型直接追加

else r += toString(val);// 如果不是基本類型遞歸調(diào)用toString方法

}

return r + "}";

}

String r = cl.getName();

// 檢查此類和所有超類的字段

do{

r += "[";

Field[] fields = cl.getDeclaredFields();

AccessibleObject.setAccessible(fields,true);// 設(shè)置一個(gè)對(duì)象數(shù)組的可訪問(wèn)標(biāo)志

// 獲取所有字段的名稱和值

for (Field field : fields){

if (!Modifier.isStatic(field.getModifiers())){

if (!r.endsWith("[")) r += ",";

r += field.getName() + "=";

Class type = field.getType();

Object val = field.get(obj);// 返回obj對(duì)象中用這個(gè)Field對(duì)象描述的字段的值

if (type.isPrimitive()) r += val;// 如果是基本類型直接追加

else r += toString(val);// 如果不是基本類型遞歸調(diào)用toString方法

}

}

r += "]";

cl = cl.getSuperclass();

}

while (cl != null);

return r;

}

}

輸出

java.util.ArrayList[elementData=class java.lang.Object[]{java.lang.Integer[value=1][][],java.lang.Integer[value=4][][],java.lang.Integer[value=9][][],java.lang.Integer[value=16][][],java.lang.Integer[value=25][][],null,null,null,null,null},size=5][modCount=5][][]

API

java.lang.reflect.AccessibleObject

void setAccessible(boolean flag)

設(shè)置或取消這個(gè)可訪問(wèn)對(duì)象的可訪問(wèn)標(biāo)志,如果拒絕訪問(wèn)則拋出一個(gè)IllegalAccessException異常

static void setAccessible(AccessibleObject[] array, boolean flag)

這是一個(gè)便利方法,用于設(shè)置一個(gè)對(duì)象數(shù)組的可訪問(wèn)標(biāo)志。

5、使用反射編寫(xiě)泛型數(shù)組代碼

CopyOfTest.java

/**

* 使用反射編寫(xiě)泛型數(shù)組代碼

*/

public class CopyOfTest {

public static void main(String[] args) {

int[] a = {1,2,3};

a = (int[]) goodCopyOf(a,10);

System.out.println(Arrays.toString(a));

String[] b = {"Tom","Dick","Harry"};

b = (String[]) goodCopyOf(b,10);

System.out.println(Arrays.toString(b));

//以下調(diào)用將生成異常

b = (String[]) badCopyOf(b,10);

}

public static Object[] badCopyOf(Object[] a, int newLength){

Object[] newArray = new Object[newLength];

System.arraycopy(a,0,newArray,0,Math.min(a.length,newLength));

return newArray;

}

public static Object goodCopyOf(Object a, int newLength){

Class cl = a.getClass();

if(!cl.isArray()) return null;

Class componentType = cl.getComponentType();// 返回表示數(shù)組的元素類型的Class

int length = Array.getLength(a);

Object newArray = Array.newInstance(componentType, newLength);// 使用反射包里的Array構(gòu)造一個(gè)新數(shù)組,提供兩個(gè)參數(shù),一個(gè)是數(shù)組的元素類型,一個(gè)是數(shù)組的長(zhǎng)度

System.arraycopy(a,0,newArray,0,Math.min(length,newLength));

return newArray;

}

}

輸出

[1, 2, 3, 0, 0, 0, 0, 0, 0, 0]

[Tom, Dick, Harry, null, null, null, null, null, null, null]

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;

at com.company.reflection.CopyOfTest.main(CopyOfTest.java:20)

API

java.lang.reflect.Array

static Object get(Object array,int index)

static void set(Object array,int index,Object newValue)

static int getLength(Object array)

返回給定數(shù)組的長(zhǎng)度

static Object newInstance(Class componentType,int Length)

返回一個(gè)有給定類型、給定大小的新數(shù)組

6、調(diào)用任意方法和構(gòu)造器

Method類中有一個(gè)invoke方法,允許調(diào)用包裝在Method對(duì)象中的方法。invoke方法的簽名是:

Object invoke(Object obj,Object... args)

第一個(gè)參數(shù)是隱式參數(shù),其余的對(duì)象提供了顯示參數(shù)。

對(duì)于靜態(tài)方法,第一個(gè)參數(shù)可以忽略,即可以將它設(shè)置為null。

MethodTableTest.java

/**

* 使用反射調(diào)用任意方法和構(gòu)造器

*/

public class MethodTableTest {

public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

// 獲取指向square和sqrt方法的方法指針

Method square = MethodTableTest.class.getMethod("square", double.class);// 平方

Method sqrt = Math.class.getMethod("sqrt", double.class);// 平方根

// 打印x和y值表

printTable(1,10,10,square);

printTable(1,10,10,sqrt);

}

public static double square(double x){

return x * x;

}

public static void printTable(double from, double to, int n, Method f) throws InvocationTargetException, IllegalAccessException {

// 打印該方法作為表頭

System.out.println(f);

double dx = (to - from) / (n - 1);

for (double x = from; x <= 10; x += dx){

double y = (Double) f.invoke(null,x);

System.out.printf("%10.4f | %10.4f%n",x,y);

}

}

}

輸出

public static double com.company.reflection.MethodTableTest.square(double)

1.0000 | 1.0000

2.0000 | 4.0000

3.0000 | 9.0000

4.0000 | 16.0000

5.0000 | 25.0000

6.0000 | 36.0000

7.0000 | 49.0000

8.0000 | 64.0000

9.0000 | 81.0000

10.0000 | 100.0000

public static double java.lang.Math.sqrt(double)

1.0000 | 1.0000

2.0000 | 1.4142

3.0000 | 1.7321

4.0000 | 2.0000

5.0000 | 2.2361

6.0000 | 2.4495

7.0000 | 2.6458

8.0000 | 2.8284

9.0000 | 3.0000

10.0000 | 3.1623

API

java.lang.reflect.Method

public Object invoke(Object implicitParamter, Object[] explicitParamters)

調(diào)用這個(gè)對(duì)象描述的方法,傳入給定參數(shù),并返回方法的返回值。對(duì)于靜態(tài)方法,傳入null作為隱式參數(shù)。

總結(jié)

以上是生活随笔為你收集整理的java反射随意值_Java反射笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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