学习目标与内容:
1.什么是反射机制
获取指定名称的字节码文件进行加载并获取其中的内容并调用(1.获取对象的字节码2.调用其中的内容,字段,方法,构造函数)
2.为什么要用反射机制
1.提高程序的扩展性
2.用起来相对方便
3.反射怎么使用
2。配置文件(动态参数)
3.动态信息的放置到配置文件中
Class中的forName();方法
反射中获取本类构造函数的方法:Constructor(Constructor提供了一个类的单个构造函数的信息和访问):构造器对象;
反射可以拿到的内容:(对应的参数类型的class对象,如String.class) Field(字段): method:
setAccessibl:暴力访问-可以拿到本类私有的
newInstance:创建一个新实例 (空参构造函数)
field.Accessible(true):暴力访问
反射:获取方法 getInvoke();
首先要明确获取class对象的三种方式
1.通过Object方法中的getClass方法
2.通过每个对象中特有的静态获取class类的方法
3.通过获取对象的class字符串,然后通过Class中的forName进行解析。(扩展性强,只需传递对应的字符串进入到forName()方法即可)比较简单方便。
4.String className =“Person”;如果peron放在包里面,需要把包名写全才能读取到Person类
如:it.conts.Person
public class HqClass {
public static void main(String[] args) throws ClassNotFoundException {
// myClass1();
// myClass2();
myClass3();
}
private static void myClass1() {
/* 获取class文件的三种方式
* 1.Object中的getClass()方法
* 需要:
*1.明确类2.创建对象
*
* */
Person p = new Person();
Class clazz1 = p.getClass();
Class clazz2 = p.getClass();
System.out.println(clazz1 == clazz2);
}
private static void myClass2() {
/*获取class的第二种方法
* 每个类创建后都有自身的--静态的获取calss的方法
* 前提条件:
* 1。明确类。2还需要用到静态成员
* */
Class clazz1 = Person.class;
Class clazz2 = Person.class;
System.out.println(clazz1 == clazz2);
}
private static void myClass3() throws ClassNotFoundException {
/*获取class文件中的第三种方法
* 1.将calss对象用字符串String封装起来
* 2.用Class类中的方法forName();方法解析其中的class对象
*
* */
String className ="Person";
Class clazz1 = Class.forName(className);
System.out.println(clazz1);
}
}
(反射机制中获取calss中的构造函数)
/*早期:new 先根据new的类名称找到该类的字节码文件,加载进内场,创建对象,再创建该字节码对应的Person对象。
- 如:it.cons.Person p = new it.cons.Person();
- 现在我们可以 使用如下方法
- String name = “it.cons.Person”;
- Class clazz = Clazz.forName(name);
- Object obj = clazz.newInstance();拿到一个空参构造函数(反射)
- 需要拿到指定的构造函数:
- Object obj = clazz.newInstance(String.class,int.class);传入数据类型的class字节码文件对象。
- 反射内容:Constructor:构造器对象(对应的参数类型的class对象,如String.class) Field(字段): method:
- */
步骤
- 获取该类的字节码文件对象class
- 获取一个新的空参构造函数的实例化
- 3.获取指定的构造函数Contructor
public class ReflctDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
String name = "Person";
//加载该类进入内存,产生class对象
Class<? extends Person> clazz = (Class<? extends Person>) Class.forName(name);
//获取空参构造函数实例化
Object obj1 = clazz.newInstance();
//获取指定的构造函数
Constructor cons = clazz.getConstructor(int.class,String.class);
//通过构造函数的对象newInstance方法进行初始化。
Object obj = cons.newInstance(88,"xx");
}
}
获取class中的字段
步骤:
1.通过Field进行对象中的getDeclaredField方法获取本类私有对象
2.需要获取私有字段就暴力访问field.setAccessible(true)方法
3.新建一个实例化空参对象
4.设置获取字段值
public class ReflctDemo2 {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException {
String name ="Person";
//forName
Class clazz = Class.forName(name);
//反射 age字段 用到field方法
Field field = null;
field = clazz.getDeclaredField("age");//获取本类私有字段
//设置私有字段的值
field.setAccessible(true);//暴力访问,直接进行值得设置
//创建一个类的实例化。初始化类
Object obj= clazz.newInstance();
//设置需要改变的值
field.set(obj, 11);
//获取该类所返回的字段,没设置则返回0
Object o = field.get(obj);
System.out.println(o+":"+o1);
}
}
获取本类中所有字段的包括私有
public class ReflctDemo2 {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException {
String name ="Person";
//forName
Class clazz = Class.forName(name);
//反射 age字段 用到field方法
Field field1 = null;
//创建一个类的实例化。初始化类
Object obj= clazz.newInstance();
for (int i = 0; i < args.length; i++) {
}
Field[] fields = clazz.getDeclaredFields();//获取本类字段--包括私有字段
for (Field field : fields) {
System.out.println(field);
}
}
}
(获取class中的方法)
步骤:
1.获取class
* 2.获取class中的方法getMethod()
* 3.method.invoke(obj,null)方法运行提取出来的方法
public class ReflctMethod {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, IOException {
/*
*
*
*/
myMethod3();
}
private static void myMethod3() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
/*
* 获取class类中的有参方法
*
* 1.获取class
* 2.获取class中的方法getMethod()
* 3.method.invoke(obj,null)方法运行提取出来的方法
*
* */
Class clazz = Class.forName("Person");
Method method = clazz.getMethod("show", String.class,int.class);
Object obj = clazz.newInstance();
Object o = method.invoke(obj, "lk",78);
}
/*
* 获取class类中的无参方法
*
* 1.获取class
* 2.获取class中的方法getMethod()
* 3.method.invoke(obj,null)方法运行提取出来的方法
*
* */
private static void myMethod2() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
String name = "Person";
Class clazz = Class.forName(name);
Method method = clazz.getMethod("show", null);//新建一个空参方法
// Object obj = clazz.newInstance();
Constructor cons = clazz.getConstructor(String.class,int.class);
Object obj = cons.newInstance("xx",78);
method.invoke(obj, null);//运行一个新的空参方法
// System.out.println(obj);
}
private static void myMethod() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
String name = "Person";
Class clazz = Class.forName(name);
Object obj = clazz.newInstance();//创建一个Object实例对象
Method[] methods = clazz.getDeclaredMethods();//获取本类中的方法包括私有的,,//clazz.getMethods();//获取公有方法
for (Method method : methods) {
System.out.println(method);
}
}
}
(反射机制的练习)
1.代码功能
电脑无需new 接口对象就可以拿到别的类中的方法
思路:
配置文件:pro.properties
接口对象:Pcie
主板对象:ZhuBan
电脑对象:Reflct
1.把实现接口中的类名以字符串的形式放入配置文件中
2.主板有一个使用方法,一旦有新的PCIE类传入进来就会使用开关功能
3.电脑读取配置文件,发现有类传入主板的开关就会读取其方法。
接口
public interface Pcie {
public void open();
public void close();
}
主板类
public class ZhuBan {
public void run()
{
System.out.println("主板运行。。。");
}
public void usePci(Pcie p) {
if (p!=null) {
p.open();
p.close();
}
}
}
显卡类
public class Rx580 implements Pcie
{
public void open() {
System.out.println("显卡开启。。。");
}
public void close() {
System.out.println("显卡关闭。。。");
}
}
电脑类(反射机制)
public class ReflctTest {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException, IOException {
//创建一个主板类
ZhuBan zb = new ZhuBan();
//创建一个配置文件
Properties prop = new Properties();
//创建一个文件读取流
FileInputStream fis = new FileInputStream("G:\\BaiduYunDownload\\JAVA 复习1\\ReflctUtil\\src\\pro.properties");
//读取配置文件
prop.load(fis);
//开始for循环,判断是否有新的配置文件加载
for (int i = 0; i < prop.size(); i++) {
//读取配置文件中的类
String pci_name = prop.getProperty("pcie"+(i+1));
//获取配置文件中的类
Class clazz = Class.forName(pci_name);
//获取本类空参构造函数的实例化对象
Pcie p = (Pcie) clazz.newInstance();
//开始运行
zb.usePci(p);
}
//关闭流
fis.close();
}
}
配置文件
pcie1=Rx580
运行图解
学习产出:
提示:这里统计学习计划的总量
例如:
1、 技术笔记 2 遍
2、CSDN 技术博客 3 篇
3、 学习的 vlog 视频 7 个(反射机制-概述与应用场景)(反射机制,细节与获取class对象)(获取class对象的三种方式)(反射机制中获取calss中的构造函数)(获取class中的字段)(获取class中的方法)(反射机制的练习)
随手笔记:
1.反射:reflex 包:lang.reflct.Constructor;
1.什么是反射机制
获取指定名称的字节码文件进行加载并获取其中的内容并调用(1.获取对象的字节码2.调用其中的内容,字段,方法,构造函数)
2.为什么要用反射机制
1.提高程序的扩展性
2.用起来相对方便
3.反射怎么使用
2。配置文件(动态参数)
3.动态信息的放置到配置文件中
早期:new 先根据new的类名称找到该类的字节码文佳,加载进内场,创建对象,再创建该字节码对应的Person对象。
calforName();
反射内容:Constructor(Constructor提供了一个类的单个构造函数的信息和访问):构造器对象;可以拿到的内容:(对应的参数类型的class对象,如String.class) Field(字段): method:
setAccessibl
newInstance:创建一个新实例 (空参构造函数)
field.Accessible(true):暴力访问
反射方法:获取方法 getInvoke();
思想出错: 基本数据类型
String不是基本数据类型 整数型: short -int(Interger) -long
浮点型:float double
字节型:byte char
逻辑布尔类型:boolean