反射(Reflection)(2月26日总结)


尚硅谷代码视频:day11_反射
学习时长:1天

java反射机制概述

理解Class类并获取Class实例(重要)

类的加载与ClassLoader的理解

创建运行时类的对象(重要)

获取运行时类的完整结构

调整运行时类的指定结构(重要)(开发时做)

反射的应用:动态代理

学习思路(B站尚硅谷)

反射之前,类的实例化
使用反射,实现同上的操作
反射的强大之处,调用类的私有结构
反射和封装性的对比

两个问题

//疑问1:通过直接new的方式或反射的方式都可以调用公共的结构,开发中到底用那个?
        //建议:直接new的方式。
        //什么时候会使用:反射的方式。 反射的特征:动态性(登录或者注册)
//疑问2:反射机制与面向对象中的封装性是不是矛盾的?如何看待两个技术?
        //不矛盾。封装性(私有的用不着,可能是被公有的调用)
        //封装性:建议是否调用。反射:能否调用。

(正式认识反射)(反射难理解:在于动态性)
Class类的理解
1、加载到内存中的类,我们就称为运行时类,就作为Class的一个实例(加载到内存中的类本身,加上.calass属性,充当大Class的实例)
以前通过类去造对象,现在,类本身也是对象,大Class的一个对象。

2.换句话说,Class的实例就对应着一个运行时类。

总结(终版)
反射相关的主要API

java.lang.Class:代表一个类
java.lang.reflect.Method:代表类的方法
java.lang.reflect.Field:代表类的成员变量
java.lang.reflect.Constructor:代表类的构造器

属性class作为Class的实例
Class clazz = Person.class;

得到构造器
Constructor cons = clazz.getConstructor(String.class, int.class);
通过构造器造对象
Object obj = cons.newInstance("TOM", 12);
Person p = (Person) obj;
System.out.println(p.toString());

输出:Person{
    
    name='TOM', age=12}
在这里插入代码片
/*
    配置文件:
        放数据库配置信息,jdbc即数据库驱动
        (专门用于连接数据库:主机、端口号、用户名、密码)(即hostName,userName,port,password)

        第三方服务的账号信息 如:appKey , 秘钥
 */

    //AM    11:08讲配置文件
    新建一个配置文件:对应package--->new--->Resource Bundle就可以

    因为通过创建Properties对象加载配置信息(为什么配置文件以properties结尾?)
    

在这里插入图片描述

获取Class对象方法1

这就拿到数据库中的配置信息,可以用jdbc连接数据库
为什么把这些信息放到文件中?       方便修改:只修改一个地方,很方便
为什么讲配置文件?     为了说明第一种获取Class对象的方式是比较好的

获取Person当中的构造方法

//AM 11:35
    //建一个Person类
    //成员变量、构造方法、成员方法分别设置了不同的访问权限
    //用反射试一下
    此处省略Person类的定义

/*
Constructor[] getConstructors()
Constructor[] getDeclaredConstructors()
 */
package com.cskaoyan.constructer;

import java.lang.reflect.Constructor;

/*
Constructor[] getConstructors()
Constructor[] getDeclaredConstructors()
 */
public class Demo {
    
    
    public static void main(String[] args) throws ClassNotFoundException {
    
    
        // 获取字节码文件对象personCls
                //Class 类的实例表示正在运行的 Java 应用程序中的类和接口
                //建议copy reference        com.cskaoyan.domain.Person
        Class personCls = Class.forName("com.cskaoyan.domain.Person");

        // 获取构造方法
                // getConstructors()    返回一个包含某些 Constructor 对象的数组,
                // 这些对象反映此 Class 对象所表示的类的所有 公共 构造方法。
        Constructor[] constructors = personCls.getConstructors();

        System.out.println("获取所有public的构造方法------------");
        for (Constructor c : constructors) {
    
    
            System.out.println(c);
        }

        System.out.println("获取所有构造方法-------------");
                // getDeclaredConstructors()    返回 Constructor 对象的一个数组,
                // 这些对象反映此 Class 对象表示的类声明的所有构造方法。
        Constructor[] declaredConstructors = personCls.getDeclaredConstructors();
        for (Constructor c : declaredConstructors) {
    
    
            System.out.println(c);
        }

    }
}

获取Person当中的成员变量

/*
Field[] getFields()
Field[] getDeclaredFields()
 */

在这里插入图片描述

在这里插入图片描述

获取Person当中的成员方法

// 获取所有成员方法 Method 用来描述我们的成员方法
                // Method[] getMethods()
                //Method[] getDeclaredMethods()

在这里插入图片描述
在这里插入图片描述

获取字节码文件对象
        Class personCls = Class.forName("com.cskaoyan.domain.Person");

		System.out.println("获取所有成员方法----------");
        Method[] declaredMethods = personCls.getDeclaredMethods();
        for (Method m : declaredMethods) {
    
    
            System.out.println(m);
        }

		获取所有成员方法----------
		private void com.cskaoyan.domain.Person.eat(java.lang.String)
		public void com.cskaoyan.domain.Person.eat()
		
		System.out.println("获取单个private的成员方法--------");
        Method eatMethod2 = personCls.getDeclaredMethod("eat", String.class);
        System.out.println(eatMethod2);
		
		获取单个private的成员方法--------
		private void com.cskaoyan.domain.Person.eat(java.lang.String)
		
		

猜你喜欢

转载自blog.csdn.net/AC_872767407/article/details/113925130