(20-09-06)学习内容

学习目标与内容:

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:
  • */

步骤

  1. 获取该类的字节码文件对象class
  2. 获取一个新的空参构造函数的实例化
  3. 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值