1. 程式人生 > >Java學習總結(十四)——java反射機制,利用反射動態創建對象

Java學習總結(十四)——java反射機制,利用反射動態創建對象

Java反射 動態創建對象

一.Java反射機制
1.什麽是反射:反射就是把Java類中的各種成份影射成一個個的Java對象。例:一個類有:成員變量,方法,構造方法等,包等等信息,利用反射技術可以對一個類進行剖析,把各個組成部分影射成一個個對象。
2.Java反射常用類:
(1)Class類—可獲取類和類的成員信息
(2)Field類—可訪問類的屬性
(3)Method—可調用類的方法
(4)Constructor—可調用類的構造方法
3.如何使用反射(基本步驟):
(1)導入java.lang.reflect.*
(2)獲得需要操作的類的Java.lang.Class對象
(3)調用Class的方法獲取Field,Method等對象
(4)使用反射API進行操作(設置屬性,調用方法)
4.Class類:
(1)Class類是Java反射機制的起源和入口
(2)Class類的實例化對象代表一個正在運行的Java類或接口
·每個類都有自己的Class對象
·用於獲取與類相關的各種信息
·提供了獲取類信息的相關方法
·Class類繼承至Object類
(3)Class類存放類的結構信息
·類名;·父類,接口;·方法,構造方法,屬性;·註釋
5.獲取Class類對象的三種方式:
(1)方法一:
//方法1:對象.getClass()
Student stu=new Student();
Class clazz=stu.getClass();
(2)方法二:
//方法2:類.class
Class clazz= Student.class;
Class clazz=String.class;
方法三:
//方法3:Class.forName()
clazz=Class.forName("java.lang.String");
clazz=Class.forName("java.util.Date");
例(代碼):
學生信息類(bean)
package org.reflect.Class;

public class Student {
private String name;
private int age;
private double score;

public Student() {
}

public Student(String name, int age, double score) {
    this.name = name;
    this.age = age;
    this.score = score;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}

public double getScore() {
    return score;
}

public void setScore(double score) {
    this.score = score;
}

public void learn() {
System.out.println(this.name + "正在學習...");}
@Override
br/>}
@Override
return "Student [name=" + name + ", age=" + age + ", score=" + score

  • "]";
    }

}

獲取Class類對象測試類
package org.reflect.Class;

import java.lang.reflect.Modifier;
public class ClassDemo {

public static void main(String[] args) {
    Student stu=new Student();
    Class<?> c1=stu.getClass();//方式一
    Class<Student> c2= Student.class;//方式二
    Class<?> c3=null;
    try {
        c3=Class.forName("org.reflect.Class.Student");   // 方式三
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    System.out.println("方式一獲取的Class對象為:"+c1.getSimpleName());
    System.out.println("方式二獲取的Class對象為:"+c2);
    System.out.println("方式三獲取的Class對象為:"+c3);
    int mod=c1.getModifiers();//獲取修飾符所對應的整數
    String modifier=Modifier.toString(mod);//獲取修飾符
    System.out.println(c1+"類所用的修飾符為:"+modifier);
}

}

運行結果:
方式一獲取Class類對象:Student
方式二獲取Class類對象:reflect.Student
方式三獲取Class類對象:reflect.Student
Student類的修飾符:public
6.使用Class類獲取類的結構信息
(1)獲取類的Class對象:
技術分享圖片

(2)獲取Filed對象
技術分享圖片

(3)獲取Method對象
技術分享圖片

(4)獲取Constructor對象
技術分享圖片

代碼示例(示例均已上述Student類為基礎)
例1(獲取Filed對象)
package org.reflect.Filed;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class FiledDemo {

public static void main(String[] args) {
    Class<Student> cl=Student.class;//獲取代表Student類的Class對象
    Field[] fields=cl.getDeclaredFields();//獲取屬性對象,返回數組
    System.out.println(cl.getSimpleName()+"類中聲明的屬性有:");
    for(Field f:fields){
        String filedName=f.getName();//獲取屬性名
        Class<?> filedType=f.getType();//獲取屬性類型
        int mod=f.getModifiers();//獲取修飾符對應整數
        String modifier=Modifier.toString(mod);//獲取修飾符
        System.out.println(modifier+" "+filedType.getSimpleName()+" "+filedName);
    }
}

}

運行結果:
Student類中聲明的屬性有:
private String name
private int age
private double score
例2(獲取Method對象)
package method;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class MethodDemo {

public static void main(String[] args) {
    try {
        Class<?> cls=Class.forName("method.Student");
        Method[] methods=cls.getDeclaredMethods();
        for(Method method:methods){
            String methodName=method.getName();   // 獲取方法名稱
            Class<?> returnType=method.getReturnType();  // 獲取方法的返回值類型
            String modStr=Modifier.toString(method.getModifiers());   // 獲取方法的修飾符
            Class<?>[] paramTypes=method.getParameterTypes();   // 獲取參數類型
            System.out.print(modStr+" "+returnType.getSimpleName()+" "+methodName+"(");
            if(paramTypes.length==0){
                System.out.print(")");
            }
            for(int i=0;i<paramTypes.length;i++){   // 遍歷形式參數類型
                if(i==paramTypes.length-1){
                    System.out.print(paramTypes[i].getSimpleName()+" args"+i+")");
                }else{
                    System.out.print(paramTypes[i].getSimpleName()+" args"+i+",");
                }
            }
            System.out.println();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

}

}

運行結果:
public void eat(String args0,String args1)
public int getAge()
public void setAge(int args0)
public double getScore()
public void setScore(double args0)

7.使用反射動態創建對象
(1)方法一:
使用Class的newInstance()方法,僅適用於無參構造方法

技術分享圖片

(2)方法二:
方法二:調用Constructor的newInstance()方法,適用所有構造方法

技術分享圖片

例3(獲取Constructor對象)
package org.reflect.Constructor;

import java.lang.reflect.Constructor;

public class ConstructorDemo {

public static void main(String[] args) {
    Class<Student> cl=Student.class;//獲取Class對象,代表Student類
    try {
        Constructor<Student> con=cl.getDeclaredConstructor(String.class,int.class,double.class);//獲取散參構造方法
        Student stu=con.newInstance("張無忌",23,96.7);
        System.out.println(stu);
    } catch (Exception e) {
        e.printStackTrace();
    } 
}

}
運行結果:
Student [name=張無忌, age=23, score=96.7]
例4(動態創建方法):
package method;

import java.lang.reflect.Method;

public class InvokeMethod {

public static void main(String[] args) {
    Class<Student> cls=Student.class;
    try {
        Student stu=cls.newInstance();   // 通過反射機制實例化對象,使用此newInstance()方法,要求類中必須包含一個無參構造方法
        Method setNameMethod=cls.getMethod("setName",String.class);
        setNameMethod.invoke(stu,"風清揚");   // 使用stu對象調用setName(String name)方法,傳入"風清揚"參數
        Method getNameMethod=cls.getMethod("getName");
        System.out.println(getNameMethod.invoke(stu));  // 使用stu對象調用getName()方法,返回一個值
    } catch (Exception e) {
        e.printStackTrace();
    } 

}

}
運行結果:
風清揚

Java學習總結(十四)——java反射機制,利用反射動態創建對象