• 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

  • 相关阅读:
    c++中的explicit关键字
    数据结构简单要点总结(转)
    线程函数中访问成员变量的方法(转)
    C++中虚析构函数的作用(转)
    TransmitFile使用(发送文件)(转)
    静态分配和动态分配内存的区别(转)
    VC++ MFC 多线程及线程同步(转)
    CEdit & CRichEdit 使用技巧(转)
    memset用法详解(转)
    symbian 显示位图和SVG图(转)
  • 原文地址:https://www.cnblogs.com/xbhog/p/14987005.html
Copyright © 2020-2023  润新知