反射概述
Reflection(反射)是Java被視為動態(tài)語言的關(guān)鍵揖庄,反射機制允許程序在執(zhí)行期借助于Reflection API取得任何類的內(nèi)部信息子檀,并能直接操作任意對象的內(nèi)部屬性及方法正塌。
Java反射機制主要提供了以下功能:
在運行時構(gòu)造任意一個類的對象
在運行時獲取任意一個類所具有的成員變量和方法
在運行時調(diào)用任意一個對象的方法(屬性)
生成動態(tài)代理
Class 是一個類; 一個描述類的類.
封裝了描述方法的 Method,
描述字段的 Filed,
描述構(gòu)造器的 Constructor 等屬性.
下面我們以student為例 一一介紹
先說獲取Class對象的三種方式
1.通過類名獲取 類名.class
2.通過對象獲取 對象名.getClass()
3.通過全類名獲取 Class.forName(全類名)
//類名.class
Class<ConStudent> conSC = ConStudent.class;
System.out.print("---------類名.class---------"+"\n");
//對象名.getClass()
ConStudent conStudent = new ConStudent();
Class<? extends ConStudent> conSC1 = conStudent.getClass();
System.out.print("---------對象名.getClass()---------"+"\n");
//Class.forName(全類名)
Class<?> conSC2 = Class.forName("com.reflection.ConStudent");
System.out.print("---------Class.forName(全類名)---------");
---------類名.class---------
靜態(tài)代碼:10
---------對象名.getClass()---------
靜態(tài)代碼:10
---------Class.forName(全類名)---------
public class ConStudent {
public static int number = 10;
static {
System.out.print("靜態(tài)代碼:"+number+"\n");
}
}
通過以上方式可以看出 第二第三種方式是直接調(diào)用靜態(tài)代碼的 從方便和效率來看 第三中方式是最好的 第一種也不錯 第二種是不推薦的 個人建議 僅供參考
現(xiàn)在說一下 Constructor
先看一下 實體類
/**
-
Constructor
*/
public class ConStudent {public ConStudent(){
System.out.print("ConStudent空參構(gòu)造函數(shù)"+"\n");
}public ConStudent(double score) {
System.out.print("ConStudent有參構(gòu)造函數(shù)"+"\n");
}private ConStudent(int age) {
System.out.print("ConStudent私有構(gòu)造帶參數(shù)"+age+"\n");
}
protected ConStudent(String name){
System.out.print("ConStudent受保護的構(gòu)造參數(shù)"+name+"\n");
}
}
private static void constructor() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> conSC = Class.forName("com.reflection.ConStudent");
Constructor<?>[] constructors = conSC.getConstructors();
for (Constructor c :constructors){
System.out.print("ReflectTest所有公有構(gòu)造:"+c+"\n");
}
System.out.print("ReflectTest----------分割線-------------"+"\n");
Constructor<?>[] declaredConstructors = conSC.getDeclaredConstructors();
for (Constructor c : declaredConstructors){
System.out.print("ReflectTest所有構(gòu)造方法:"+c+"\n");
}
System.out.print("ReflectTest----------分割線-------------"+"\n");
Constructor constructor = conSC.getConstructor();
System.out.print("ReflectTest公有無參構(gòu)造方法"+constructor+"\n");
System.out.print("ReflectTest----------分割線-------------"+"\n");
Constructor<?> declaredConstructor = conSC.getDeclaredConstructor(int.class);
System.out.print("ReflectTest私有構(gòu)造方法"+declaredConstructor+"\n");
declaredConstructor.setAccessible(true);
Object o = declaredConstructor.newInstance(11);
System.out.print("ReflectTest調(diào)用私有構(gòu)造"+o+"\n");
System.out.print("ReflectTest----------分割線-------------"+"\n");
Constructor<?> declaredConstructor1 = conSC.getDeclaredConstructor(String.class);
declaredConstructor1.setAccessible(true);
Object maoge = declaredConstructor1.newInstance("maoge");
System.out.print("ReflectTest受保護的構(gòu)造:"+maoge);
}
輸出內(nèi)容
ReflectTest所有公有構(gòu)造:public com.reflection.ConStudent(double)
ReflectTest所有公有構(gòu)造:public com.reflection.ConStudent()
ReflectTest----------分割線-------------
ReflectTest所有構(gòu)造方法:protected com.reflection.ConStudent(java.lang.String)
ReflectTest所有構(gòu)造方法:private com.reflection.ConStudent(int)
ReflectTest所有構(gòu)造方法:public com.reflection.ConStudent(double)
ReflectTest所有構(gòu)造方法:public com.reflection.ConStudent()
ReflectTest----------分割線-------------
ReflectTest公有無參構(gòu)造方法public com.reflection.ConStudent()
ReflectTest----------分割線-------------
ReflectTest私有構(gòu)造方法private com.reflection.ConStudent(int)
ConStudent私有構(gòu)造帶參數(shù)11
ReflectTest調(diào)用私有構(gòu)造com.reflection.ConStudent@14ae5a5
ReflectTest----------分割線-------------
ConStudent受保護的構(gòu)造參數(shù)maoge
ReflectTest受保護的構(gòu)造:com.reflection.ConStudent@7f31245a
Process finished with exit code 0
下面看一下 Filed
實體也是三個參數(shù) 代表三種權(quán)限
/**
-
Filed
*/
public class FiledStudent {
public int age;
private String name;
protected double score;@Override
public String toString() {
return "FiledStudent{" +
"age=" + age +
", name='" + name + ''' +
", score=" + score +
'}';
}public int getAge() {
return age;
}public void setAge(int age) {
this.age = age;
}public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}public double getScore() {
return score;
}public void setScore(double score) {
this.score = score;
}
}
private static void filedTest() throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> filedSC = Class.forName("com.reflection.FiledStudent");
Field[] fields = filedSC.getFields();
for (Field f :fields){
System.out.print("ReflectTest所有公有的參數(shù):"+f+"\n");
}
System.out.print("ReflectTest----------分割線-------------"+"\n");
Field age = filedSC.getField("age");
Object o = filedSC.getConstructor().newInstance();
age.set(o,11);
FiledStudent student = (FiledStudent) o;
System.out.print("ReflectTest獲取公有參數(shù):"+student.getAge()+"\n");
System.out.print("ReflectTest----------分割線-------------"+"\n");
Field[] declaredFields = filedSC.getDeclaredFields();
for (Field f :declaredFields){
System.out.print("ReflectTest獲取所有參數(shù):"+f+"\n");
}
System.out.print("ReflectTest----------分割線-------------"+"\n");
Field name = filedSC.getDeclaredField("name");
name.setAccessible(true);
name.set(o,"Maoge");
System.out.print("ReflectTest獲取指定的私有參數(shù):"+student.getName()+"\n");
System.out.print("ReflectTest----------分割線-------------"+"\n");
Field score = filedSC.getDeclaredField("score");
score.setAccessible(true);
score.set(o,9.8);
System.out.print("ReflectTest獲取受保護的參數(shù):"+student.getScore());
}
下面看 mothed
/**
-
Method
*/
public class MethodStudent{
int age;
String name;
double score;public void showName( ){
System.out.print("(公共)姓名:");
}
private void showAge(){
System.out.print("(私有)年齡:");
}
protected void showScore(){
System.out.print("(保護)分數(shù):");
}public String printName(String name){
System.out.print("(公共string)name:"+name);
return name;
}
private double printScore(double score){
System.out.print("(私有double)score:"+score);
return score;
}
protected int printAge(int age){
System.out.print("(保護age)age:"+age);
return age;
}
}
private static void methodTest() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> methodSC = Class.forName("com.reflection.MethodStudent");
Method[] declaredMethods = methodSC.getDeclaredMethods();
for (Method m : declaredMethods){
System.out.print("ReflectTest 獲取所有的方法:"+m+"\n");
}
System.out.print("ReflectTest----------分割線-------------"+"\n");
Method[] methods = methodSC.getMethods();
for (Method m : methods){
System.out.print("ReflectTest獲取所有的公有方法"+m+"\n");
}
System.out.print("ReflectTest----------分割線-------------"+"\n");
Method score = methodSC.getDeclaredMethod("printScore", double.class);
Object o = methodSC.getConstructor().newInstance();
score.setAccessible(true);
Object invoke = score.invoke(o, 9.8);
System.out.print("ReflectTest調(diào)用制定的私有方法:"+invoke+"\n");
System.out.print("ReflectTest----------分割線-------------"+"\n");
Method printName = methodSC.getMethod("printName", String.class);
Object maoge = printName.invoke(o, "Maoge");
System.out.print("ReflectTest公有有參數(shù)方法:"+maoge+"\n");
System.out.print("ReflectTest----------分割線-------------"+"\n");
Method showName = methodSC.getMethod("showName", null);
System.out.print("ReflectTest公有無參方法:"+showName+"\n");
System.out.print("ReflectTest----------分割線-------------"+"\n");
Method printAge = methodSC.getDeclaredMethod("printAge", int.class);
printAge.setAccessible(true);
Object invoke1 = printAge.invoke(o, 20);
System.out.print("ReflectTest受保護的方法:"+invoke1);
}
這是反射的一些基礎(chǔ)使用
下面說一下動態(tài)代理 (代理可以讓我們的方法或者類進行功能擴展 解耦等好處)
新建一個接口
public interface Person {
void work();
}
新建一個接口實現(xiàn)類(被角色代理)
public class PersonImpl implements Person{
@Override
public void work() {
System.out.print("i am PersonImpl.calss");
}
}
新建一個代理角色
public class PersonHandler implements InvocationHandler {
public Object px;
public PersonHandler(Object px) {
this.px = px;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.print("do work"+"\n");
return method.invoke(px,args);
}
}
綁定代理
public class PersonProxyTest {
public static void main(String[] args) {
Person person = new PersonImpl();
Person o = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class[]{Person.class}, new PersonHandler(person));
o.work();
}
}
好了 本文到此結(jié)束 歡迎留言或私信