文章目录
尚硅谷代码视频: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对象的方式是比较好的
![](https://img-blog.csdnimg.cn/20210226214022901.png)
获取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);
}
}
}
![](https://img-blog.csdnimg.cn/20210226222444403.png)
获取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)