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進行操作(設置屬性,調用方法)
(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;
方法三:
//方法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反射機制,利用反射動態創建對象