Java核心反射機制


Java核心反射機制:

基本反射:

反射是一種動態類的處理機制,通過Class類來實現反射機制;

Class類的基本信息:

Module java.base
Package java.lang
    Class Class<T>
		java.lang.Object
 			java.lang.Class<T>

以下三種方式獲得類的反射,三者都非常重要,牢牢掌握。

  1. 利用Object類中提供getClass()方法獲取實例化對象
class Member {}
public class JavaReflectDemo {
	public static void main(String[] args) throws Exception {
		// 【操作特點】需要獲取一個類的實例化對象之后才可以獲取Class類實例
		Member member = new Member() ;	// 實例化Member類對象
		Class<?> clazz = member.getClass() ; 	// 獲取Class類實例化對象
		System.out.println(clazz);
	}
}
  1. 使用“類.class”形式
class Member {}
public class JavaReflectDemo {
	public static void main(String[] args) throws Exception {
		// 【操作特點】直接通過一個類的完整名稱可以獲取Class類實例,需要編寫import或編寫完整類名稱
		Class<?> clazz = Member.class ; 	// 獲取Class類實例化對象
		System.out.println(clazz);
	}
}
  1. 使用Class類內部提供的forName()方法根據類的完整名稱獲取實例化對象
class Member {}
public class JavaReflectDemo {
	public static void main(String[] args) throws Exception {
		// 【操作特點】通過名稱字符串(包.類)可以獲取Class類實例,可以不使用import導入
        // 獲取Class類實例化對象
		Class<?> clazz = Class.forName("cn.xbhog.demo.Member");	
		System.out.println(clazz);
	}
}

反射獲取實例化對象:

package com.xbhog.反射機制;
class Member{
    public Member() {	// 構造方法
        System.out.println("【構造方法】實例化Member類對象.");
    }
    @Override
    public String toString() {
        return "【toString()覆寫】博客地址:http://www.cnblogs.com/xbhog";
    }

}
public class 反射獲取對象 {
    public static void main(String[] args) throws Exception {
        // 獲取Class類實例化對象
        Class<?> clazz = Class.forName("com.xbhog.反射機制.Member"); 	
        // 反射機制可以獲取任意類實例化對象(等價於關鍵字“new”),所以返回的類型為Object
        Object obj = clazz.getDeclaredConstructor().newInstance() ;// 實例化對象
        System.out.println(obj);
    }
}

反射的機制可以更加方便開發者實現解耦和設計;

反射與類操作:

在反射機制下,可以自動獲取並調用任意一個類中的組成結構(成員屬性、方法),使得代碼的編寫更加靈活。

反射獲取類結構:

package com.xbhog.反射機制;
interface IMessage{
    public void send();
}
interface IChannelService{
    public Boolean connect();
}

abstract class AbstractBase{}
public class Mail extends AbstractBase implements IMessage,IChannelService{
    @Override
    public void send() {
        if(this.connect()){
            System.out.println("發送信息成功");
        }
    }

    @Override
    public Boolean connect() {
        return true;
    }
}
package com.xbhog.反射機制;
public class MailTest {
    public static void main(String[] args) {
        Class<Mail> aClass = Mail.class;
        System.out.println(aClass.getPackage());  //獲取類的包名
        Class<? super Mail> superclass = aClass.getSuperclass(); //獲取父類對象信息
        System.out.println(superclass.getName());  //獲取父類名字
        System.out.println(superclass.getSuperclass().getName());  //獲取父類的父類的名字

        /*獲取接口信息*/
        Class<?>[] interfaces = aClass.getInterfaces();
        for (Class<?> anInterface : interfaces) {
            System.out.println(anInterface.getName());
        }
    }
}

反射調用構造方法:

反射還可以調用構造方法,構造方法是類中的重要組成部分,也是實例化對象時必須調用的方法。

實例:

import java.lang.reflect.Constructor;
class Mail {
	private String msg ;
	public Mail() {}// 無參構造
	public Mail(String msg) {// 單參構造
		System.out.println("【構造方法】調用Mail類單參構造方法,實例化對象");
		this.msg = msg ;
	}
	@Override
	public String toString() {	// 對象信息
		return "【toString()覆寫】消息內容:" + this.msg;
	}
}
public class JavaReflectDemo {
	public static void main(String[] args) throws Exception {
		Class<?> cls = Mail.class ; // 獲取指定類的Class對象
		Constructor<?>[] constructors = cls.getDeclaredConstructors() ; // 獲取全部構造
		for (Constructor<?> cons : constructors) {
			System.out.println(cons);
		}
		// 獲取單參構造並且參數類型為String的構造方法對象實例
		Constructor<?> cons = cls.getDeclaredConstructor(String.class) ;
		Object obj = cons.newInstance("www.cnblog.cn/xbhog") ;// 調用單參構造實例化對象
		System.out.println(obj);
	}
}

反射調用方法:

反射機制中除了獲取類中的方法定義外,最為重要的功能就是可以利用Method類中的invoke()方法並結合實例化對象(Object類型即可)實現放射的調用。

反射調用類中的setter、getter方法(重點)

package com.xbhog.反射機制.方法;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class Member{
    private String name;
    public void setName(String name){
        this.name = name;

    }
    public String getName(){
        return this.name;
    }
}

public class getter_Setter {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class<?> cls = Member.class;
        String value = "xbhog";
        //實例化Member對象
        Object obj = cls.getDeclaredConstructor().newInstance();
        //反射調用方法需要明確的知道方法的名稱以及方法中的參數類型
        String setMethodName ="setName";
        Method setmethod = cls.getDeclaredMethod(setMethodName, String.class);  //獲取指定方法
        setmethod.invoke(obj,value);  //對象.setName(value)
        String getMethodName = "getName";
        Method getMethod = cls.getDeclaredMethod(getMethodName);  //get沒有參數
        System.out.println(getMethod.invoke(obj));//對象.getName();
    }
}

通過放射實現的方法調用的最大的特點是可以直接利用Object類型的實例化對象進行調用的,但是在獲取對象時需要明確的知道方法名稱以及方法的參數類型。

Field類的作用:

在實際開發中,Field中的getType()方法使用的較多,可以通過其來確定屬性的類型

示例:

import java.lang.reflect.Field;

class Member{
    private String name;
    public void setName(String name){
        this.name = name;

    }
    public String getName(){
        return this.name;
    }
}
public class FIeldDemo {
    public static void main(String[] args) throws Exception {
        //獲取Member類
        Class<?> cls = Member.class;
        //實例化
        Object obj = cls.getDeclaredConstructor().newInstance();
        //成員屬性name的類型
        Field name = cls.getDeclaredField("name");
        //獲取詳細信息
        System.out.println(name.getType().getName());
        //獲取簡略信息
        System.out.println(name.getType().getSimpleName());
    }
}

結果:

java.lang.String
String


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM