当前位置 博文首页 > lk00000111的博客:(20-09-06)学习内容

    lk00000111的博客:(20-09-06)学习内容

    作者:[db:作者] 时间:2021-09-12 15:04

    学习目标与内容:

    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  {