Java反射機(jī)制可能是漲薪關(guān)鍵!
Java核心反射機(jī)制
基本反射
反射是一種動(dòng)態(tài)類的處理機(jī)制,通過 Class類 來實(shí)現(xiàn)反射機(jī)制;
Class類的基本信息:
- Module java.base
- Package java.lang
- Class Class<T>
- java.lang.Object
- java.lang.Class<T>
以下三種方式獲得類的反射,三者都非常重要,牢牢掌握。
一、利用Object類中提供getClass()方法獲取實(shí)例化對(duì)象
- class Member {}
- public class JavaReflectDemo {
- public static void main(String[] args) throws Exception {
- // 【操作特點(diǎn)】需要獲取一個(gè)類的實(shí)例化對(duì)象之后才可以獲取Class類實(shí)例
- Member member = new Member() ; // 實(shí)例化Member類對(duì)象
- Class<?> clazz = member.getClass() ; // 獲取Class類實(shí)例化對(duì)象
- System.out.println(clazz);
- }
- }
二、使用“類.class”形式
- class Member {}
- public class JavaReflectDemo {
- public static void main(String[] args) throws Exception {
- // 【操作特點(diǎn)】直接通過一個(gè)類的完整名稱可以獲取Class類實(shí)例,需要編寫import或編寫完整類名稱
- Class<?> clazz = Member.class ; // 獲取Class類實(shí)例化對(duì)象
- System.out.println(clazz);
- }
- }
三、使用Class類內(nèi)部提供的forName()方法根據(jù)類的完整名稱獲取實(shí)例化對(duì)象
- class Member {}
- public class JavaReflectDemo {
- public static void main(String[] args) throws Exception {
- // 【操作特點(diǎn)】通過名稱字符串(包.類)可以獲取Class類實(shí)例,可以不使用import導(dǎo)入
- // 獲取Class類實(shí)例化對(duì)象
- Class<?> clazz = Class.forName("cn.xbhog.demo.Member");
- System.out.println(clazz);
- }
- }
反射獲取實(shí)例化對(duì)象
- package com.xbhog.反射機(jī)制;
- class Member{
- public Member() { // 構(gòu)造方法
- System.out.println("【構(gòu)造方法】實(shí)例化Member類對(duì)象.");
- }
- @Override
- public String toString() {
- return "【toString()覆寫】博客地址:http://www.cnblogs.com/xbhog";
- }
- }
- public class 反射獲取對(duì)象 {
- public static void main(String[] args) throws Exception {
- // 獲取Class類實(shí)例化對(duì)象
- Class<?> clazz = Class.forName("com.xbhog.反射機(jī)制.Member");
- // 反射機(jī)制可以獲取任意類實(shí)例化對(duì)象(等價(jià)于關(guān)鍵字“new”),所以返回的類型為Object
- Object obj = clazz.getDeclaredConstructor().newInstance() ;// 實(shí)例化對(duì)象
- System.out.println(obj);
- }
- }
反射的機(jī)制可以更加方便開發(fā)者實(shí)現(xiàn)解耦和設(shè)計(jì);
反射與類操作
在反射機(jī)制下,可以自動(dòng)獲取并調(diào)用任意一個(gè)類中的組成結(jié)構(gòu)(成員屬性、方法),使得代碼的編寫更加靈活。
反射獲取類結(jié)構(gòu)
- package com.xbhog.反射機(jī)制;
- 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("發(fā)送信息成功");
- }
- }
- @Override
- public Boolean connect() {
- return true;
- }
- }
- package com.xbhog.反射機(jī)制;
- 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(); //獲取父類對(duì)象信息
- System.out.println(superclass.getName()); //獲取父類名字
- System.out.println(superclass.getSuperclass().getName()); //獲取父類的父類的名字
- /*獲取接口信息*/
- Class<?>[] interfaces = aClass.getInterfaces();
- for (Class<?> anInterface : interfaces) {
- System.out.println(anInterface.getName());
- }
- }
- }
反射調(diào)用構(gòu)造方法
反射還可以調(diào)用構(gòu)造方法,構(gòu)造方法是類中的重要組成部分,也是實(shí)例化對(duì)象時(shí)必須調(diào)用的方法。
實(shí)例:
- import java.lang.reflect.Constructor;
- class Mail {
- private String msg ;
- public Mail() {}// 無參構(gòu)造
- public Mail(String msg) {// 單參構(gòu)造
- System.out.println("【構(gòu)造方法】調(diào)用Mail類單參構(gòu)造方法,實(shí)例化對(duì)象");
- this.msg = msg ;
- }
- @Override
- public String toString() { // 對(duì)象信息
- return "【toString()覆寫】消息內(nèi)容:" + this.msg;
- }
- }
- public class JavaReflectDemo {
- public static void main(String[] args) throws Exception {
- Class<?> cls = Mail.class ; // 獲取指定類的Class對(duì)象
- Constructor<?>[] constructors = cls.getDeclaredConstructors() ; // 獲取全部構(gòu)造
- for (Constructor<?> cons : constructors) {
- System.out.println(cons);
- }
- // 獲取單參構(gòu)造并且參數(shù)類型為String的構(gòu)造方法對(duì)象實(shí)例
- Constructor<?> cons = cls.getDeclaredConstructor(String.class) ;
- Object obj = cons.newInstance("www.cnblog.cn/xbhog") ;// 調(diào)用單參構(gòu)造實(shí)例化對(duì)象
- System.out.println(obj);
- }
- }
反射調(diào)用方法
反射機(jī)制中除了獲取類中的方法定義外,最為重要的功能就是可以利用Method類中的invoke()方法并結(jié)合實(shí)例化對(duì)象(Object類型即可)實(shí)現(xiàn)放射的調(diào)用。
反射調(diào)用類中的setter、getter方法【重點(diǎn)】
- package com.xbhog.反射機(jī)制.方法;
- 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";
- //實(shí)例化Member對(duì)象
- Object obj = cls.getDeclaredConstructor().newInstance();
- //反射調(diào)用方法需要明確的知道方法的名稱以及方法中的參數(shù)類型
- String setMethodName ="setName";
- Method setmethod = cls.getDeclaredMethod(setMethodName, String.class); //獲取指定方法
- setmethod.invoke(obj,value); //對(duì)象.setName(value)
- String getMethodName = "getName";
- Method getMethod = cls.getDeclaredMethod(getMethodName); //get沒有參數(shù)
- System.out.println(getMethod.invoke(obj));//對(duì)象.getName();
- }
- }
通過放射實(shí)現(xiàn)的方法調(diào)用的最大的特點(diǎn)是可以直接利用Object類型的實(shí)例化對(duì)象進(jìn)行調(diào)用的,但是在獲取對(duì)象時(shí)需要明確的知道方法名稱以及方法的參數(shù)類型。
Field類的作用
在實(shí)際開發(fā)中,F(xiàn)ield中的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;
- //實(shí)例化
- Object obj = cls.getDeclaredConstructor().newInstance();
- //成員屬性name的類型
- Field name = cls.getDeclaredField("name");
- //獲取詳細(xì)信息
- System.out.println(name.getType().getName());
- //獲取簡(jiǎn)略信息
- System.out.println(name.getType().getSimpleName());
- }
- }
結(jié)果:
- java.lang.String String