当前位置: 首页>JAVA>正文

java編程,java.lang.Class:是反射的源頭

java編程,java.lang.Class:是反射的源頭

??????一、反射概述

1. java.lang.Class:是反射的源頭

我們創建一個類,通過編譯,生成對應的.calss文件,之后使用java.exe加載(jvm的類加載器)此.class文件,此.class文件加載到內存以后,就是一個運行時類,存在緩存區,那么這個運行時類的本身就是一個class的實例

  • 每一個運行時類只加載一次
  • 有了Class實例以后,我們才可以進行如下的操作:
    • 創建對應的運行時類的對象(重點)
    • 可以獲取對象的運行時類的完整結構(屬性、方法、構造器、內部類、、、)(理解)
    • 調用對應的運行時類的指定的結構(屬性、方法)(重點)

在反射以前,如何創建一個類的對象,并調用其中的方法屬性

public void test1() {Person p = new Person();p.setAge(10);p.setName("AA");p.show();System.out.println(p);}

有了反射,可以通過反射創建一個類的對象,并調用其中的方法,下面詳細說

public void test2(www.lanboyulezc.cn ) throws Exception {Class clazz www.shentuylgw.cn= Person.class;//1.創建clazz對應的運行時類Person類的對象Person p = (Person)clazz.newInstance();System.out.println(p);//2.通過反射調用運行時類的指定屬性,public name的修改方式Field f1 = clazz.getField("name");f1.set(p, www.shentuylgw.cn"LiuDaHua");System.out.println(p);//private age的方式Field f2 = clazz.getDeclaredField("age");f2.setAccessible(true);f2.set(p, 20);System.out.println(p);//3.通過反射調用運行時類的指定方法 public修飾的Method m1 = clazz.getMethod("show");// 執行m1.invoke(p);// 帶參數的方法Method m2 = clazz.getMethod("display", String.class);m2.invoke(p, "www.jintianxuesha.com");}

java編程。?

二、如何獲取Class的實例

1.調用運行時類本身的.class屬性

Class clazz = Person.class;
System.out.println(clazz.getName());Class clazz1 = String.class;
System.out.println(clazz1.getName());

2.通過運行時類的對象獲取

Person p = new Person();
Class clazz2 = p.getClass();
System.out.println(clazz.getName());

3.通過Class的靜態方法獲取,通過此方式,體會反射的動態性

String className = "com.atguigu.java.Person";Class clazz4 = Class.forName(className);	   
System.out.println(clazz4);

4.通過類的加載器

ClassLoader classLoader = this.getClass().getClassLoader();
Class clazz5 = classLoader.loadClass(className);
System.out.println(clazz5.getName());

整個代碼

public void test4() throws Exception {//1.調用運行時類本身的.class屬性Class clazz = Person.class;System.out.println(clazz.getName());Class clazz1 = String.class;System.out.println(clazz1.getName());//2.通過運行時類的對象獲取Person p = new Person(www.chuancenpt.com);Class clazz2 = p.getClass();System.out.println(clazz.getName(www.tengyao3zc.cn));//3.通過Class的靜態方法獲取,通過此方式,體會反射的動態性String className = "com.atguigu.java.Person";Class clazz4 = Class.forName(className);System.out.println(clazz4);//4.通過類的加載器ClassLoader classLoader =www.jujinyule.com this.getClass().getClassLoader();Class clazz5 =www.xingyunylpt.com classLoader.loadClass(className);System.out.println(clazz5.getName());}

java反射調用類的方法?回到頂部

三、創建運行時類對象

1. 獲取Class的實例

通常直接使用類名.class , 例如Person.class

當然了,上面的幾種方法都是可以的

String className = "com.atguigu.java.Person";
Class clazz = Class.forName(className);

2.創建運行時類對象

創建對應的運行時類的對象,使用的是newInstance(),實際上就是運用了運行時類的空參數的構造器

java反射獲取字段類型?要想能夠創建成功

  • 要求對應的運行時類要有空參數的構造器
  • 構造器的權限修飾符的權限要足夠
Object obj = clazz.newInstance();//調用的是空參構造器
Person p = (Person)obj;
System.out.println(p);

全部代碼

public void test1(www.mLgjzc.cn) throws Exception {// 獲取Class實例Class clazz www.feihongyul.cn= Person.class;//創建對應的運行時類的對象,使用的是newInstance(),實際上就是運用了運行時類的空參數的構造器//要想能夠創建成功,①要求對應的運行時類要有空參數的構造器,②構造器的權限修飾符的權限要足夠Object obj www.youy2zhuce.cn= clazz.newInstance();//調用的是空參構造器Person p = (Person)obj;System.out.println(p);		}

回到頂部

四、通過反射獲取類的完整結構

1.獲取運行時類的屬性

1.getFields() 返回 :表示公共字段的 Field 對象的數組,只能獲取運行時類中以及父類中聲明的為public的屬性

Field[] fiels = clazz.getFields();
for(int i=0;i<fiels.length;i++) {System.out.println(fiels[i]);}

2.getDeclaredFields() :獲取運行時類本身聲明的所有的屬性,包括私有的

Field[] fiels1 = clazz.getDeclaredFields();
for(int i=0;i<fiels1.length;i++) {System.out.println(fiels1[i].getName());}//增強for循環
for(Field f:fiels1) {System.out.println(f.getName());
}

java中類有哪些?

2.獲取屬性的各個部分的內容

權限修飾符 變量類型 變量名

1.獲取每個屬性的權限修飾符

Field[] field = clazz.getDeclaredFields();for(Field i:field) {//1.獲取每個屬性的權限修飾符int a = i.getModifiers();String str1 = Modifier.toString(a);System.out.print(str1+"   ");}

2.獲取屬性的變量類型

Field[] field = clazz.getDeclaredFields();for(Field i:field) {//2.獲取屬性的變量類型Class type = i.getType();System.out.print(type+"  ");}

3.獲取屬性名

Class clazz = Person.class;Field[] field = clazz.getDeclaredFields();for(Field i:field) {//3.獲取屬性名System.out.print(i.getName());System.out.println();}

3.獲取運行時類的方法(重點)

java 反射 invoke。1.getMethods() 獲取運行時類及其父類中所有聲明為public的方法

Class clazz = Person.class;
Method[] m1 = clazz.getMethods();for(Method m:m1) {System.out.println(m);}

2.getDeclaredMethods() 獲取運行時類本身聲明的所有的方法

Method[] methods = clazz.getDeclaredMethods();for(int i=0;i<methods.length;i++) {System.out.println(methods[i]);}

4.獲取方法的各個部分的內容

注解 權限修飾符 返回值類型 方法名 形參列表 異常

1.注解

Class clazz = Person.class;Method[] m1 = clazz.getMethods();for(Method m:m1) {Annotation[] an = m.getAnnotations();for(Annotation a:an) {System.out.println(a);}
}

2.權限修飾符

int a = m.getModifiers();
String str1 = Modifier.toString(a);
System.out.print(str1+"  ");

java中反射的概念、3.返回值類型

Class return1 = m.getReturnType();
System.out.print(return1+"  ");

4.方法名

System.out.print(m.getName()+"   ");

5.形參列表

System.out.print("(");
Class[] params = m.getParameterTypes();
for(Class p : params) {System.out.print(p.getName());
}
System.out.println(")"+"   ");

6.拋的異常

Class[] ex = m.getExceptionTypes();for(Class e:ex) {System.out.print(e.getName());}//   for(int i=0;i<ex.length;i++) {
//	System.out.print(ex[i].getName());//       }

5.獲取構造器

	@Testpublic void test5() throws Exception {Class clazz = Class.forName("com.atguigu.java.Person");Constructor[] cons = clazz.getDeclaredConstructors();for(Constructor c : cons) {System.out.println(c);}}

6.獲取運行時類的父類

@Testpublic void test6() {Class clazz = Person.class;Class super1 = clazz.getSuperclass();System.out.println(super1);}

javasuper的作用、

7.獲取帶泛型的父類

@Testpublic void test7() {Class clazz = Person.class;Type type1 = clazz.getGenericSuperclass();System.out.println(type1);}

8.獲取父類的泛型(重點)

@Testpublic void test8() {Class clazz = Person.class;Type type1 = clazz.getGenericSuperclass();ParameterizedType param= (ParameterizedType)type1;Type[] ars = param.getActualTypeArguments();System.out.println((Class)ars[0]);}

9.獲取實現的接口

@Testpublic void test9() {Class clazz = Person.class;Class[] i = clazz.getInterfaces();for(Class a:i) {System.out.println(a);}}

10.獲取所在的包

@Testpublic void test10() {Class clazz = Person.class;Package p = clazz.getPackage();System.out.println(p);}

全部代碼如下:

package com.atguigu.java;import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;import org.junit.Test;/*** 通過反射獲取類的完整結構* * @author MD**/
public class TestField {/*** 1.獲取運行時類的屬性*/@Testpublic void test1() {Class clazz = Person.class;//1.getFields() 返回 :表示公共字段的 Field 對象的數組 // 只能獲取運行時類中以及父類中聲明的為public的屬性
//		Field[] fiels = clazz.getFields();
//		for(int i=0;i<fiels.length;i++) {
//			System.out.println(fiels[i]);
//		}//2.getDeclaredFields() :獲取運行時類本身聲明的所有的屬性Field[] fiels1 = clazz.getDeclaredFields();for(int i=0;i<fiels1.length;i++) {System.out.println(fiels1[i].getName());}//增強for循環for(Field f:fiels1) {System.out.println(f.getName());}}/*** 權限修飾符 變量類型  變量名* 2.獲取屬性的各個部分的內容* */@Testpublic void tset2() {Class clazz = Person.class;Field[] field = clazz.getDeclaredFields();for(Field i:field) {//1.獲取每個屬性的權限修飾符int a = i.getModifiers();String str1 = Modifier.toString(a);System.out.print(str1+"   ");//2.獲取屬性的變量類型Class type = i.getType();System.out.print(type+"  ");//3.獲取屬性名System.out.print(i.getName());System.out.println();}}/*** 3.獲取運行時類的方法*/@Testpublic void test3() {Class clazz = Person.class;//1.getMethods() 獲取運行時類及其父類中所有聲明為public的方法//		Method[] m1 = clazz.getMethods();
//		for(Method m:m1) {
//			System.out.println(m);
//		}//2.getDeclaredMethods() 獲取運行時類本身聲明的所有的方法Method[] methods = clazz.getDeclaredMethods();for(int i=0;i<methods.length;i++) {System.out.println(methods[i]);}}/*** 4.獲取方法的各個部分的內容* 注解  權限修飾符   返回值類型	方法名    形參列表    異常* */@Testpublic void test4() {Class clazz = Person.class;Method[] m1 = clazz.getMethods();for(Method m:m1) {//1.注解Annotation[] an = m.getAnnotations();for(Annotation a:an) {System.out.println(a);}//2.權限修飾符int a = m.getModifiers();String str1 = Modifier.toString(a);System.out.print(str1+"  ");//3.返回值類型Class return1 = m.getReturnType();System.out.print(return1+"  ");//4.方法名System.out.print(m.getName()+"   ");//5.形參列表System.out.print("(");Class[] params = m.getParameterTypes();for(Class p : params) {System.out.print(p.getName());}System.out.println(")"+"   ");//6.拋的異常Class[] ex = m.getExceptionTypes();for(Class e:ex) {System.out.print(e.getName());}
//			for(int i=0;i<ex.length;i++) {
//				System.out.print(ex[i].getName());
//			}System.out.println();}}/*** 5.獲取構造器* @throws Exception */@Testpublic void test5() throws Exception {Class clazz = Class.forName("com.atguigu.java.Person");Constructor[] cons = clazz.getDeclaredConstructors();for(Constructor c : cons) {System.out.println(c);}}/*** * 6.獲取運行時類的父類*/@Testpublic void test6() {Class clazz = Person.class;Class super1 = clazz.getSuperclass();System.out.println(super1);}/*** 7.獲取帶泛型的父類*/@Testpublic void test7() {Class clazz = Person.class;Type type1 = clazz.getGenericSuperclass();System.out.println(type1);}/*** 8.獲取父類的泛型*/@Testpublic void test8() {Class clazz = Person.class;Type type1 = clazz.getGenericSuperclass();ParameterizedType param= (ParameterizedType)type1;Type[] ars = param.getActualTypeArguments();System.out.println((Class)ars[0]);}/*** 9.獲取實現的接口*/@Testpublic void test9() {Class clazz = Person.class;Class[] i = clazz.getInterfaces();for(Class a:i) {System.out.println(a);}}/*** 10.獲取所在的包*/@Testpublic void test10() {Class clazz = Person.class;Package p = clazz.getPackage();System.out.println(p);}
}

回到頂部

五、調用運行時類的指定結構

java反射怎么理解、

1.調用運行時類指定的屬性并賦值

1. 獲取指定的屬性

getField(String fieldName):獲取運行時類中聲明為public的指定的屬性名為fieldName的屬性

Field name = clazz.getField("name");

2.創建運行時類的對象

Person p = (Person) clazz.newInstance();
System.out.println(p);

3.將運行時類的指定屬性賦值

name.set(p, "Jerry");
System.out.println(p);

給age賦值,private需要注意

java lang string、getDeclareField(String fieldName):獲取運行時類中指明為filedName的屬性

	Field age = clazz.getDeclaredField("age");//由于屬性權限修飾符的限制,為了保證可以給屬性賦值,需要在操作前使得此屬性可被操作age.setAccessible(true);//私有的設置成可以訪問的age.set(p,1);System.out.println(p);

給id賦值,默認的修飾符

	Field id = clazz.getDeclaredField("id");id.set(p,10);System.out.println(p);

2.調用運行時類中指定的方法

1.getMethod(String methodName,Class...params)獲取指定的public方法,方法名,參數列表

Class clazz = Person.class;
Method m1 = clazz.getMethod("show");

2.創建運行時類的對象

Person p =(Person)clazz.newInstance();

3.和屬性相似,這里是invoke關鍵字里面是對象和參數列表,或許還有返回值,用Object接收

Object returnVal = m1.invoke(p);
System.out.println(returnVal);//沒返回值的打印為null

Java三要素。4.獲取toString()有返回值的

Method m2 = clazz.getMethod("toString");
Object returnVal1 = m2.invoke(p);
System.out.println(returnVal1);

5.獲取display()帶參數的

Method m3 = clazz.getMethod("display",String.class);
m3.invoke(p, "china");

6.獲取info()靜態的方法

Method m4 = clazz.getMethod("info");
m4.invoke(Person.class);

7.獲取Test() 私有的帶參數的有返回值的

Method m5 = clazz.getDeclaredMethod("Test",String.class,Integer.class);
m5.setAccessible(true);
Object o = m5.invoke(p,"測試",5);
System.out.println(o);

3.調用指定的構造器,創建類對象

public void test3() throws InstantiationException, Exception {Class clazz = Person.class;Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);cons.setAccessible(true);Person p = (Person)cons.newInstance("迪麗熱巴",20);System.out.println(p);}

全部代碼

package com.atguigu.java;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;import org.junit.Test;/*** ******調用對應的運行時類的指定的結構(屬性、方法)* @author MD**/
public class TestField1 {/*** 調用運行時類指定的屬性* @throws Exception * @throws NoSuchFieldException */@Testpublic void test1() throws Exception {Class clazz = Person.class;//1.獲取指定的屬性//getField(String fieldName):獲取運行時類中聲明為public的指定的屬性名為fieldName的屬性Field name = clazz.getField("name");//2.創建運行時類的對象Person p = (Person) clazz.newInstance();System.out.println(p);//3.將運行時類的指定屬性賦值name.set(p, "Jerry");System.out.println(p);//給age賦值,private需要注意//getDeclareField(String fieldName):獲取運行時類中指明為filedName的屬性Field age = clazz.getDeclaredField("age");//由于屬性權限修飾符的限制,為了保證可以給屬性賦值,需要在操作前使得此屬性可被操作age.setAccessible(true);//私有的設置成可以訪問的age.set(p,1);System.out.println(p);//給id賦值,默認的修飾符Field id = clazz.getDeclaredField("id");id.set(p,10);System.out.println(p);}/*** 調用運行時類中指定的方法* @throws Exception * @throws NoSuchMethodException */@Testpublic void test2() throws NoSuchMethodException, Exception {Class clazz = Person.class;//getMethod(String methodName,Class...params)獲取指定的public方法,方法名,參數列表Method m1 = clazz.getMethod("show");//創建運行時類的對象Person p =(Person)clazz.newInstance();//和屬性相似,這里是invoke關鍵字里面是對象和參數列表,或許還有返回值,用Object接收Object returnVal = m1.invoke(p);System.out.println(returnVal);//獲取toString()有返回值的Method m2 = clazz.getMethod("toString");Object returnVal1 = m2.invoke(p);System.out.println(returnVal1);//獲取display()帶參數的Method m3 = clazz.getMethod("display",String.class);m3.invoke(p, "china");//獲取info()靜態的方法Method m4 = clazz.getMethod("info");m4.invoke(Person.class);//獲取Test() 私有的帶參數的有返回值的Method m5 = clazz.getDeclaredMethod("Test",String.class,Integer.class);m5.setAccessible(true);Object o = m5.invoke(p,"測試",5);System.out.println(o);	}/*** 調用指定的構造器,創建類對象* @throws Exception * @throws InstantiationException */@Testpublic void test3() throws InstantiationException, Exception {Class clazz = Person.class;	Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);cons.setAccessible(true);Person p = (Person)cons.newInstance("迪麗熱巴",20);System.out.println(p);}
}

回到頂部

六、ClassLoader

類加載器是用來把類(class)裝載進內存

1.獲取一個系統類加載器

ClassLoader loader1 = ClassLoader.getSystemClassLoader();
System.out.println(loader1);

2.獲取系統類加載器的父類加載器,即擴展類加載器

ClassLoader loader2 = loader1.getParent();
System.out.println(loader2);

3.獲取擴展類加載器的父類加載器,即引導類加載器,加載的是核心庫,打印為null

ClassLoader loader3 = loader2.getParent();
System.out.println(loader3);

4.測試當前類由哪個類加載器進行加載

Class clazz1 = Person.class;
ClassLoader loader4 = clazz1.getClassLoader();
System.out.println(loader4);//系統類加載器

1. 描述一下JVM加載class文件的原理機制?

JVM中類的裝載是由ClassLoader和它的子類來實現的,

Java ClassLoader 是一個重要的Java運行時系統組件。它負責在運行時查找和裝入類文件的類。

https://www.nshth.com/java/338902.html
>

相关文章:

  • java編程
  • java反射調用類的方法
  • java反射獲取字段類型
  • java中類有哪些
  • java 反射 invoke
  • java中反射的概念
  • javasuper的作用
  • java反射怎么理解
  • pdf去水印軟件免費版,java批量去除pdf簽名,刪除簽名圖標
  • java多線程面試題及答案,JAVA8線程池THREADPOOLEXECUTOR底層原理及其源碼解析
  • java編程,java.lang.Class:是反射的源頭
  • java基礎面試題及答案,HTML CSS 基礎 面試題
  • java編寫軟件工具,Xson:Java對象序列化和反序列化工具
  • nlp預訓練模型,NLP-D62-nlp比賽D31刷題D15
  • kafka如何使用,kafka javax.management.InstanceAlreadyExistsException: kafka.consumer:
  • ssm畢設項目企業部門報銷管理g9d62(java+VUE+Mybatis+Maven+Mysql+sprnig)
  • java小游戲合集,java 煙花_Java 美麗的煙花
  • table列合并,poi操作excel之列合并
  • 找不到指定模塊怎么辦,在烏版圖安裝軟件包時候報錯:E:無法定位軟件包
  • 學云計算好就業嗎,對不起,云計算技術又走錯路了
  • 數電模電基礎知識總結,數電模電實驗課程
  • java的基礎知識,「JavaSE」-面向對象
  • 擴展內存,Java編程內存分析簡要
  • java多線程面試題及答案,【階段一】java之面向對象上
  • java 工作流框架,Activiti工作流使用之SpringBoot整合Activiti
  • 模型的應用形態包括哪些,模型設計準則
  • c語言程序設計培訓班南寧,南寧從零開始學習編程
  • 服務器,Spring Security oAuth2創建認證服務器模塊
  • Java jdk14.0.1安裝簡單步驟
  • 安裝ug12.0當前頁面的腳本發生錯誤,ug提示找不到html文件,[圖文教程] 以下文件無法加載,導致打開操作失敗: 使用當前搜索選項找不到文件,部件已卸載.
  • java執行cmd命令找不到指定文件,java編譯找不到文件_解決cmd運行java程序“找不到文件”提示的方案
  • 線上學畫畫的機構排名,拍樂云推出業內首個「線上美術教學音視頻方案」,打造極致互動體驗
  • day18-java
  • 取兩者中較小值函數,求兩個數中的較大值
  • java多線程面試題及答案,python中的多任務-多線程和多進程
  • 關于Arthas如何遠程監視Java程序
  • Java8 Stream流中的 collect() 方法,遠比你想象中的強大
  • 劉德華《天若有情》,天若有情