1. 程式人生 > 實用技巧 >Java反射基礎程式碼

Java反射基礎程式碼

說明:本文,在轉載時,對內容略作修改,更方便閱讀,程式碼做了除錯和格式整理,總之,希望在原作者基礎上,更加方便大家學習和理解。

一、java反射

1、反射:動態獲取類的資訊,以及動態呼叫物件的方法的功能。可以理解為動態看透類的能力。

2、主要功能:

①在執行時判斷任意一個物件所屬的類;

②在執行時構造任意一個類的物件;

③在執行時判斷任意一個類所具有的成員變數和方法;

④在執行時呼叫任意一個物件的方法;

⑤生成動態代理。

通過java反射機制,可以在程式中訪問已經裝載到JVM中的java物件的描述,實現訪問、檢測和修改描述java物件本身資訊的功能。java反射機制的功能十分強大,java.lang.reflect包中提供了對該功能的支援。

二、通過反射獲取類的三種方法

  1. //1、第一種方式-->Class.forName("類名字串");
  2. //注:類名字串是"包名+類名" 返回Class的物件。(這種是最常用的方法)
  3. Class c1=Class.forName("csdn.Student");
  4. //2、第二種方式-->先建立物件,再用物件呼叫getClass()方法,即例項物件.getClass().返回執行時類。
  5. //任何一個java物件都有getClass()方法
  6. Student s=new Student();
  7. Class c2 = s.getClass();
  8. //3、第三種方式-->類名.class。返回Class的物件。(每個類都有class屬性)
  9. Class c3=Student.class

三、通過反射可以獲取到的主要描述資訊

1、獲得屬性

2、獲得方法:

3、獲得構造方法:

4、獲得其他資訊:

四、具體演示反射

父類:Person類

  1. package com.liuxd.reflection;
  2. /**
  3. * Created by Liuxd on 2018/8/14.
  4. */
  5. public class Person {
  6. public String name;// 姓名
  7. public int age;// 年齡
  8. public Person() {
  9. super();
  10. }
  11. public Person(String name, int age) {
  12. super();
  13. this.name = name;
  14. this.age = age;
  15. }
  16. public String showInfo() {
  17. return "name=" + name + ", age=" + age;
  18. }
  19. }

子類:Student類

  1. package com.liuxd.reflection;
  2. /**
  3. * Created by Liuxd on 2018/8/14.
  4. */
  5. public class Student extends Person implements Study {
  6. public String className;// 班級
  7. private String address;// 住址
  8. public Student() {
  9. super();
  10. }
  11. public Student(String name, int age, String className, String address) {
  12. super(name, age);
  13. this.className = className;
  14. this.address = address;
  15. }
  16. public Student(String className) {
  17. this.className = className;
  18. }
  19. public String toString() {
  20. return "姓名:" + name + ",年齡:" + age + ",班級:" + className + ",住址:"
  21. + address;
  22. }
  23. public String getAddress() {
  24. return address;
  25. }
  26. public void setAddress(String address) {
  27. this.address = address;
  28. }
  29. }


介面:study

  1. package com.liuxd.reflection;
  2. /**
  3. * Created by Liuxd on 2018/8/14.
  4. */
  5. public interface Study {
  6. //僅為了演示獲得介面,就沒有寫抽象方法
  7. }
1、獲得屬性:
  1. package com.liuxd.reflection;
  2. import java.lang.reflect.Field;
  3. /**
  4. * Created by Liuxd on 2018/8/14.
  5. */
  6. public class TestAttributes {
  7. public static void main(String[] args) {
  8. Class stu = null;
  9. try {
  10. stu = Class.forName("com.liuxd.reflection.Student");
  11. } catch (ClassNotFoundException e) {
  12. e.printStackTrace();
  13. }
  14. // 獲取物件的所有公有屬性。
  15. Field[] fields = stu.getFields();
  16. for (Field f : fields) {
  17. System.out.println(f);
  18. }
  19. System.out.println("---------------------");
  20. // 獲取物件所有屬性,但不包含繼承的。
  21. Field[] declaredFields = stu.getDeclaredFields();
  22. for (Field ff : declaredFields) {
  23. System.out.println(ff);
  24. }
  25. }
  26. }

執行結果:

public java.lang.String com.liuxd.reflection.Student.className
public java.lang.String com.liuxd.reflection.Person.name
public int com.liuxd.reflection.Person.age
---------------------
public java.lang.String com.liuxd.reflection.Student.className
private java.lang.String com.liuxd.reflection.Student.address

2、獲得方法:

  1. package com.liuxd.reflection;
  2. import java.lang.reflect.Method;
  3. /**
  4. * Created by Liuxd on 2018/8/14.
  5. */
  6. public class TestMethod {
  7. public static void main(String[] args) {
  8. Class stu = null;
  9. try {
  10. stu = Class.forName("com.liuxd.reflection.Student");
  11. } catch (ClassNotFoundException e) {
  12. e.printStackTrace();
  13. }
  14. // 獲取物件的所有公共方法
  15. Method[] methods = stu.getMethods();
  16. for (Method m : methods) {
  17. System.out.println(m);
  18. }
  19. System.out.println("---------------------");
  20. // 獲取物件所有方法,但不包含繼承的
  21. Method[] declaredMethods = stu.getDeclaredMethods();
  22. for (Method ms : declaredMethods) {
  23. System.out.println(ms);
  24. }
  25. }
  26. }

執行結果:

public java.lang.String com.liuxd.reflection.Student.toString()
public java.lang.String com.liuxd.reflection.Student.getAddress()
public void com.liuxd.reflection.Student.setAddress(java.lang.String)
public java.lang.String com.liuxd.reflection.Person.showInfo()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
---------------------
public java.lang.String com.liuxd.reflection.Student.toString()
public java.lang.String com.liuxd.reflection.Student.getAddress()
public void com.liuxd.reflection.Student.setAddress(java.lang.String)

3、獲得構造方法:

為了演示區別,將Student類中引數為className的構造方法的public修飾符改為protected,檢視效果。

  1. package com.liuxd.reflection;
  2. import java.lang.reflect.Constructor;
  3. /**
  4. * Created by Liuxd on 2018/8/14.
  5. */
  6. public class TestConstructor {
  7. public static void main(String[] args) {
  8. Class stu = null;
  9. try {
  10. stu = Class.forName("com.liuxd.reflection.Student");
  11. } catch (ClassNotFoundException e) {
  12. e.printStackTrace();
  13. }
  14. // 獲取物件所有的公共構造方法
  15. Constructor[] constructors = stu.getConstructors();
  16. for (Constructor c : constructors) {
  17. System.out.println(c);
  18. }
  19. System.out.println("---------------------");
  20. // 獲取物件所有的構造方法
  21. Constructor[] declaredConstructors = stu.getDeclaredConstructors();
  22. for (Constructor con : declaredConstructors) {
  23. System.out.println(con);
  24. }
  25. }
  26. }

執行結果為:

public com.liuxd.reflection.Student(java.lang.String)
public com.liuxd.reflection.Student(java.lang.String,int,java.lang.String,java.lang.String)
public com.liuxd.reflection.Student()
---------------------
public com.liuxd.reflection.Student(java.lang.String)
public com.liuxd.reflection.Student(java.lang.String,int,java.lang.String,java.lang.String)
public com.liuxd.reflection.Student()

4、獲得其他:

  1. package com.liuxd.reflection;
  2. /**
  3. * Created by Liuxd on 2018/8/14.
  4. */
  5. public class TestOther {
  6. public static void main(String[] args) {
  7. Class stu = null;
  8. try {
  9. stu = Class.forName("com.liuxd.reflection.Student");
  10. } catch (ClassNotFoundException e) {
  11. e.printStackTrace();
  12. }
  13. System.out.println(stu.getName());//獲取物件全限定名稱
  14. System.out.println(stu.getPackage());// 獲取包名
  15. Class[] interfaces = stu.getInterfaces();//獲取該類實現的所有介面
  16. for (Class in : interfaces) {
  17. System.out.println(in);
  18. }
  19. }
  20. }

執行結果為:
com.liuxd.reflection.Student
package com.liuxd.reflection
interface com.liuxd.reflection.Study

5、通過反射例項化物件,呼叫物件方法

  1. package com.liuxd.reflection;
  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.Method;
  4. /**
  5. * Created by Liuxd on 2018/8/14.
  6. */
  7. public class TestReflect {
  8. @SuppressWarnings("unchecked")
  9. public static void main(String[] args) {
  10. try {
  11. //獲取class物件
  12. Class c = Class.forName("com.liuxd.reflection.Student");
  13. Student stu1 = (Student) c.newInstance();
  14. // 第一種方法,例項化預設構造方法,呼叫set賦值
  15. stu1.setAddress("深圳南山");
  16. System.out.println(stu1);
  17. // 第二種方法 取得全部的建構函式 使用建構函式賦值
  18. Constructor<Student> constructor = c.getConstructor(String.class,
  19. int.class, String.class, String.class);
  20. Student stu2 = (Student) constructor.newInstance("李四", 18, "七班", "深圳");
  21. System.out.println(stu2);
  22. /**
  23. * 獲取方法並執行方法
  24. */
  25. Method show = c.getMethod("showInfo");//獲取showInfo()方法
  26. Object object = show.invoke(stu2);//呼叫showInfo()方法
  27. System.out.println(object);
  28. } catch (Exception e) {
  29. e.printStackTrace();
  30. }
  31. }
  32. }

執行結果為:

姓名:null,年齡:0,班級:null,住址:深圳南山
姓名:李四,年齡:18,班級:七班,住址:深圳
name=李四, age=18