zoukankan      html  css  js  c++  java
  • Java 核心类库之反射机制

    1:什么是反射机制?

    2:反射机制它可以做什么呢?  

    3:反射机制对应的API又是什么?

    1):通过反射机制来获取一个对象的全限定名称(完整包名),和类名;

    2):实例化Class对象

    3):获取对象的父类与实现的接口

    4):获取类中的所有的方法或者单个方法

    5):使用反射调用方法 && 使用反射调用静态方法

    6):使用反射调用数组参数

    7):使用反射,动态拷贝数组

    7):获取一个类中所有的构造器,获取单个不带参数的构造器,获取带参数的构造器

    8):使用反射调用构造器---->创建对象

    9):动态加载资源文件

    1.什么是反射机制

    反射机制是在运行状态中,对于任意一个类,都能够知道类所有的属性和方法,对于任意一个对象,

    都能调用它的方法和属性,这种动态获取方法和属性,动态调用方法和属性的功能,称为Java的反射机制。

    2.反射机制它可以做什么

    反射机制主要提供以下功能:

    1:在运行时,判断任意一个对象所属的类 。

    2:在运行时,构造任意一个类的对象。

    3:在运行时,判断任意一个类所具有的成员变量和方法。

    4:在运行时,任意调用一个类中的方法。

    5:生成动态代理。

     5.反射机制对应的API又是什么

     通过一个对象来获取一个对象的全限定名称(完整包名)

    包名:Classinstance 类名:MethodD

    private static void GetName() {
    		Class claz=MethodD.class;//获取对象的类
    		String classname=claz.getName();
    		System.out.println(classname);//打印出:Classinstance.MethodD
    	}
    

     

    实例化Class对象

    package net.xsoftlab.baike;
    public class TestReflect {
        public static void main(String[] args) throws Exception {
            Class<?> class1 = null;
            Class<?> class2 = null;
            Class<?> class3 = null;
            // 一般采用这种形式
            class1 = Class.forName("net.xsoftlab.baike.TestReflect");
            class2 = new TestReflect().getClass();
            class3 = TestReflect.class;
            System.out.println("类名称   " + class1.getName());
            System.out.println("类名称   " + class2.getName());
            System.out.println("类名称   " + class3.getName());
        }
    }
    

    获取对象的父类与实现的接口

    package Classinstance;
    
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.Serializable;
    
    //获取父类和实现的接口
    public class GetparentAndInterface implements Serializable,ActionListener {
    
    	public static void main(String[] args) {
    		Class<?> claz=GetparentAndInterface.class;//获取对象
    		//获取父类
    		//返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。
    		Class<?>parent=claz.getSuperclass();
    		System.out.println(parent);//打印父类:class java.lang.Object
    		//获取该类中所有的实现接口
    		// getInterfaces()确定此对象所表示的类或接口实现的接口。
    		Class<?>[] InterFace=claz.getInterfaces();
    		for (Class<?> class1 : InterFace) {
    			System.out.println(class1);
    		}
    
    	}
    
    	public void actionPerformed(ActionEvent e) {
    		
    	}
    
    }
    

    使用反射来调用方法

    package Classinstance;
    
    import java.lang.reflect.Method;
    
    //使用反射调用方法
    class InvokeClass {
    	public void methodOne() {
    		System.out.println("调用不带参数的方法!");
    	}
    
    	public void methodTwo(String name) {
    		System.out.println("调用带一个参数的方法!" + name);
    	}
    
    	private String methodThree(String name, int age) {
    		System.out.println("调用私有带两个参数的方法!" + name + "," + age);
    		return name + "," + age;
    	}
    }
    
    public class MethodInvokeDemo {
    	public static void main(String[] args) throws Exception {
    		//获取类对象
    		Class<InvokeClass> clazz = InvokeClass.class;
    		//获取方法
    		Method md = clazz.getMethod("methodOne");
    		Object dowork = md.invoke(clazz.newInstance());//invoke();
    		System.out.println(dowork);
    
    		//调用带参数的方法
    		Method md1 = clazz.getMethod("methodTwo", String.class);
    		Object dowork1 = md1.invoke(clazz.newInstance(), "张三");//invoke();
    		System.out.println(dowork1);
    
    		//调用私有带两个参数的方法
    		Method md2 = clazz.getDeclaredMethod("methodThree", String.class, int.class);
    		md2.setAccessible(true);//设置可访问的私有成员
    		Object dowork2 = md2.invoke(clazz.newInstance(), "张三", 18);//invoke();
    		System.out.println(dowork2);

    //使用反射调用静态方法
            Method md3 = clazz.getDeclaredMethod("methodThree", String.class, int.class);
            md3.setAccessible(true);//设置可访问的私有成员
            Object dowork3 = md3.invoke(null, "张三", 18);//invoke();
            System.out.println(dowork3); } }

     

    使用反射来调用数组参数(情况1:数组元素类型数基本类型  情况2:数组元素类型是引用类型)

    package Classinstance;
    
    import java.lang.reflect.Method;
    import java.util.Arrays;
    
    class Method2 {
    	public static void dowork(int[] arr) {
    		System.out.println("dowork被调用了" + Arrays.toString(arr));
    	}
    
    	public static void dowork2(String[] arr) {
    		System.out.println("dowork2被调用了" + Arrays.toString(arr));
    	}
    }
    
    public class MethodInvokeDemo2 {
    	//使用反射调用数组参数(可变参数)
    	public static void main(String[] args) throws Exception {
    		Class<Method2> clazz = Method2.class;
    		//情况1:数组元素类型数基本类型
    		Method md = clazz.getMethod("dowork", int[].class);
    		//md.invoke(null, 1,2,3,4,5,6);error
    		//Object dw=md.invoke(null, new int[]{1,2,3,4,5,6});
    		Object dw = md.invoke(null, new Object[] { new int[] { 1, 2, 3, 4, 5, 6 } });
    		System.out.println(dw);
    		//情况2:数组元素类型是引用类型		
    		Method md1 = clazz.getMethod("dowork2", String[].class);
    		//md.invoke(null, new String[]{"a","b","c"});error
    		Object dw1 = md1.invoke(null, new Object[] { new String[] { "a", "b", "c" } });
    		System.out.println(dw1);
    	}
    }
    

     

    使用反射机制,动态拷贝数组

    package Classinstance;
    
    import java.lang.reflect.Array;
    import java.util.Arrays;
    
    //使用反射机制,动态拷贝数组
    public class ArrayDemo {
    	public static void main(String[] args) {
    		int[] src = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    		int[] dest = new int[10];
    		System.out.println(Arrays.toString(src));
    		Arraycopy(src, 2, dest, 3, 5);
    		System.out.println(Arrays.toString(dest));
    	}
    
    	public static void Arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
    		//源数组和目标数组必须是数组类型
    		if (!src.getClass().isArray() || !dest.getClass().isArray()) {
    			throw new ArrayStoreException("源数组和目标数组不是数组类型");
    		}
    		//源数组和目标数组不能为null
    		if (src == null || dest == null) {
    			throw new NullPointerException("源数组和目标数组不能为null");
    		}
    		//源数组和目标数组的数组类型必须一致
    		if (src.getClass().getComponentType() != dest.getClass().getComponentType()) {
    			throw new ArrayStoreException("源数组和目标数组元素类型不一致");
    		}
    		//源数组和目标数组不想索引越界
    		if (srcPos < 0 || destPos < 0 || length < 0 || srcPos + length > Array.getLength(src)
    				|| destPos + length > Array.getLength(dest)) {
    			throw new IndexOutOfBoundsException("索引越界");
    		}
    		//获取需要拷贝的元素
    		for (int index = srcPos; index < srcPos + length; index++) {
    			//给目标数组数组元素
    			Object val = Array.get(src, index);
    			Array.set(dest, destPos, val);
    			destPos++;
    		}
    	}
    }
    

     

     获取类中的所有的方法或者单个方法

    package Classinstance;
    
    import java.lang.reflect.Method;
    
    class MethodD {
    	public void method1() {
    
    	}
    
    	public void method2(String name) {
    	}
    
    	private String method3(String name, int age) {
    		return name + "," + age;
    	}
    }
    
    public class GetMethodDemo {
    
    	private static GetMethodDemo class2;
    
    	//使用反射获取类中的方法
    	public static void main(String[] args) throws Exception {
    		getAll();
    		getOne();
    		GetName();
    	}
    
    	//通过一个对象来获取一个对象的全限定名称(完整包名)
    	private static void GetName() {
    		Class claz = MethodD.class;//获取对象的类
    		String classname = claz.getName();
    		System.out.println(classname);//打印出:Classinstance.MethodD
    	}
    
    	//获取类中的指定的一个方法
    	private static void getOne() throws Exception {
    		Class<MethodD> clasz = MethodD.class;
    		//获取类不带参数的方法
    		Method md = clasz.getMethod("method1");
    		//获取类中指定带一个参数的方法
    		Method md1 = clasz.getMethod("method2", String.class);
    		//获取类私有指定带两个参数的方法
    		Method md2 = clasz.getDeclaredMethod("method3", String.class, int.class);
    		System.out.println(md2);
    	}
    
    	private static void getAll() {//获取类中的所有方法
    		Class<MethodD> clasz = MethodD.class;
    		/*
    		 * 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,
    		 * 包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
    		 */
    		Method[] md = clasz.getDeclaredMethods();
    		System.out.println(md.length);
    		for (Method method : md) {
    			System.out.println(method);
    		}
    
    	}
    
    }
    

    获取一个类中所有的构造器,获取单个不带参数的构造器,获取带参数的构造器

    package Classinstance;
    
    import java.lang.reflect.Constructor;
    
    class User {
    	public User() {
    
    	}
    
    	public User(String name) {
    
    	}
    
    	private User(String name, int age) {
    
    	}
    }
    
    //获取构造器
    public class GetConstructor {
    	public static void main(String[] args) throws Exception {
    		getAll();
    	}
    
    	//获取所有构造器
    	private static void getAll() throws Exception {
    		//1):获取构造器所在类的对象
    		Class<User> claz = User.class;
    		
    		//2):获取对象中的所有构造器
    		Constructor<?>[] con = claz.getConstructors();//getConstructors()获取类中带public的构造器,返回一个Constructors数组
    		for (Constructor<?> constructor : con) {
    			System.out.println(constructor);
    		}
    		Constructor<?>[] con1 = claz.getDeclaredConstructors();//getDeclaredConstructors()获取类中带所有的构造器,跟访问权限无关,返回一个Constructors数组
    		for (Constructor<?> constructor : con1) {
    			System.out.println(constructor);
    		}
    		//获取public User()的构造器
    		Constructor<User> con2 = claz.getConstructor();
    		System.out.println(con2);
    		// 获取public User(String name)的构造器
    		//注意:必须用getDeclaredConstructor();有访问权限才可以
    		Constructor<User> con3 = claz.getDeclaredConstructor(String.class, int.class);
    		System.out.println(con3);
    	}
    }
    

     

     使用反射调用构造器---->创建对象

    package Classinstance;
    
    //使用反射调用构造器-->创建对象
    import java.lang.reflect.Constructor;
    
    class Peson {
    	public Peson() {
    		System.out.println("无参数构造器");
    	}
    
    	public Peson(String name) {
    		System.out.println("有参数构造器" + name);
    	}
    
    	private Peson(String name, int age) {
    		System.out.println("有参数构造器" + name + "," + age);
    	}
    }
    
    public class CteateObject {
    	public static void main(String[] args) throws Exception {
    		Cteate();
    	}
    
    	public static void Cteate() throws Exception {
    		//获取构造器对象
    		Class<Peson> clasz = Peson.class;
    		Constructor<?> con1 = clasz.getDeclaredConstructor();
    		Constructor<?> con2 = clasz.getDeclaredConstructor(String.class);
    		Constructor<?> con3 = clasz.getDeclaredConstructor(String.class, int.class);
    		//创建对象
    		con2.newInstance("张三");//newInstance();创建此 Class 对象所表示的类的一个新实例
    		//设置构造器可以访问
    		con3.setAccessible(true);
    		con3.newInstance("李四", 15);
    	}
    }
    

     

     动态加载资源文件

    package Classinstance;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;
    
    //动态加载资源文件
    public class LoadResourceDemo {
    	public static void main(String[] args) throws Exception {
    		text1();
    		text2();
    	}
    
    	//最好用的方法
    	private static void text2() throws Exception {
    		Properties p = new Properties();
    		ClassLoader loader = Thread.currentThread().getContextClassLoader();
    		InputStream inStream = loader.getResourceAsStream("db.properties");
    		p.load(inStream);
    		System.out.println(p);
    	}
    
    	private static void text1() throws Exception {
    		//一般方式
    		Properties p = new Properties();
    		InputStream inStream = new FileInputStream("file/db.properties");//
    		p.load(inStream);
    		System.out.println(p);
    	}
    
    }
    
  • 相关阅读:
    第十一周课程总结
    第十周学习总结
    第九周课程总结&实验报告(七)
    第八周课程总结&实验报告(六)
    第七周总结&第五次实验报告
    第六周学习总结&第四次实验报告
    课程总结
    第十四周课程总结&实验报告(简单记事本的实现)
    第十三周课程总结
    第十二周
  • 原文地址:https://www.cnblogs.com/jiangxifanzhouyudu/p/6744855.html
Copyright © 2011-2022 走看看