• Java基础教程——反射机制


    Java反射机制

    • Java反射机制是Java语言的一个重要特性,使得Java语言具备“动态性”:
    • 在运行时获取任意一个对象所属的类的相关信息;
    • 在运行时构造任意一个类的对象;
    • 在运行时获取任意一个类所具有的成员变量和方法;
    • 在运行时调用任意一个对象的方法。

    JAVA反射机制是构建框架技术的基础。

    例如后续学习的Spring框架等,都使用到反射技术;

    • Java的反射机制依靠反射API实现,反射API主要包括以下几个类,后续学习:
    • java.lang.Class类:代表一个类;
    • java.lang.reflect.Field 类:类的成员变量(成员变量也称为类的属性);
    • java.lang.reflect.Method类:类的方法;
    • java.lang.reflect.Constructor 类:类的构造方法;
    • java.lang.reflect.Array类:动态创建数组,以及访问数组的元素的静态方法。

    通过Class实例化对象

    _class.newInstance()
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    public class T31反射创建对象 {
    	public static void main(String[] args) throws ClassNotFoundException, InstantiationException,
    			IllegalAccessException, NoSuchMethodException, SecurityException,
    			IllegalArgumentException, InvocationTargetException {
    		Class<?> _class = Class.forName("java.lang.String");
    		// 1.直接创建对象
    		Object newInstance = _class.newInstance();
    		// 说明创建了一个空字符串:""
    		System.out.println(newInstance.equals(""));
    		// 2.通过获取构造方法,构造对象
    		Constructor<?> _constr = _class.getConstructor(_class);
    		Object _obj = _constr.newInstance("实例化对象");
    		System.out.println(_obj);
    	}
    }
    
    true
    实例化对象
    

    私有成员也能获取

    包括:构造,变量,方法
    getDeclaredXXX可以获取私有成员

    package ahjava.p07reflect;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    public class T32获取私有成员一览 {
    	public static void main(String[] args) throws Exception {
    		// get构造方法();
    		// getMethod();
    		getField();
    	}
    	static void get构造方法() {
    		Class<Dog> _class = Dog.class;
    		Constructor[] _ctors = null;
    		System.out.println("---↓↓↓getConstructors()获取public构造方法");
    		_ctors = _class.getConstructors();
    		for (Constructor c : _ctors) {
    			System.out.println(c);
    		}
    		System.out.println("---↓↓↓getDeclaredConstructors()获取全部构造方法");
    		_ctors = _class.getDeclaredConstructors();
    		for (Constructor c : _ctors) {
    			System.out.println(c);
    		}
    	}
    	static void getMethod() throws NoSuchMethodException, SecurityException {
    		Class<Dog> _class = Dog.class;
    		Method[] mtds;
    		System.out.println("===↓↓↓.getMethods()所有public方法,包括继承来的方法=====");
    		mtds = _class.getMethods();
    		for (Method md : mtds) {
    			System.out.println(md);
    		}
    		System.out.println("===↓↓↓.getDeclaredMethods()所有自己声明的方法=====");
    		mtds = _class.getDeclaredMethods();
    		for (Method md : mtds) {
    			System.out.println(md);
    		}
    		System.out.println("=====获取指定方法=====");
    		System.out.println("-----.getMethod()只能获取public方法");
    		System.out.println("-----.getDeclaredMethod()可获取private方法");
    		// (方法名,参数类型...)
    		Method m = _class.getDeclaredMethod("_someMethod", String.class);
    		System.out.println(m);
    	}
    	static void getField()
    			throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
    		Class<Dog> _class = Dog.class;
    		Field[] fields;
    		System.out.println("=====.getFields()=====");
    		fields = _class.getFields();
    		for (Field fd : fields) {
    			System.out.println(fd);
    		}
    		System.out.println("=====.getDeclaredFields()=====");
    		fields = _class.getDeclaredFields();
    		for (Field fd : fields) {
    			System.out.println(fd);
    		}
    		System.out.println("=====获取指定变量=====");
    		System.out.println("-----.getDeclaredField(...)");
    		Field f = _class.getDeclaredField("fPrivate");
    		System.out.println(f);
    	}
    }
    class Dog {
    	private Dog() {
    		System.out.println("private构造方法");
    	}
    	public Dog(String name) {
    		System.out.println("public构造方法");
    	}
    	public Dog(String name, int n) {
    		System.out.println("public构造方法");
    	}
    	// -----变量-----
    	private String fPrivate = "private变量";
    	protected String fProtected = "protected变量";
    	public String fPublic = "public变量";
    	String fDefault = "未修饰变量";
    	// -----方法-----
    	private void _mPrivate() {
    	}
    	protected void _mProtected() {
    	}
    	public void _mPublic() {
    	}
    	void _mDefault() {
    	}
    	// ---
    	private void _someMethod(String s) {
    	}
    }
    
    =====.getFields()=====
    public java.lang.String ahjava.p07reflect.Dog.fPublic
    =====.getDeclaredFields()=====
    private java.lang.String ahjava.p07reflect.Dog.fPrivate
    protected java.lang.String ahjava.p07reflect.Dog.fProtected
    public java.lang.String ahjava.p07reflect.Dog.fPublic
    java.lang.String ahjava.p07reflect.Dog.fDefault
    =====获取指定变量=====
    -----.getDeclaredField(...)
    private java.lang.String ahjava.p07reflect.Dog.fPrivate
    

    获取私有成员应用:

    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    public class T33获取私有成员应用 {
    	public static void main(String[] args) throws Exception {
    		Class<Dog2> _class = Dog2.class;
    		// 获取(私有)构造方法
    		Constructor<Dog2> _constr = _class.getDeclaredConstructor();
    		_constr.setAccessible(true);
    		Object _obj = _constr.newInstance();
    		// 获取(私有)成员变量
    		Field _field = _class.getDeclaredField("name");
    		_field.setAccessible(true);
    		System.out.println("原内容:" + _field.get(_obj));
    		_field.set(_obj, "二狗");
    		// 获取(私有)方法(方法名,参数类型列表)
    		Method m = _class.getDeclaredMethod("show", String.class, int.class);
    		m.setAccessible(true);
    		// __invoke:调用对象obj的当前方法,args为方法参数;
    		m.invoke(_obj, "狗", 2);
    	}
    }
    class Dog2 {
    	private Dog2() {
    		System.out.println("私有构造方法");
    	}
    	private String name = "SS";
    	private void show(String str1, int n2) {
    		System.out.println(name + ":'汪汪'" + str1 + n2);
    	}
    }
    
    私有构造方法
    原内容:SS
    二狗:'汪汪'狗2
    
  • 相关阅读:
    接口的幂等性怎么设计?
    python 实现批量 WKT 转 KML
    火星坐标(GCJ02)高精度反算
    GDAL RasterIO 速度测试程序
    linux下 QtCreator 运行不显示 qDebug 输出的问题
    我使用的 clang-format 配置文件
    cephadm 离线安装部署 ceph 集群记录
    解决vcpkg无法交叉编译arm64版本 HDF5 库的问题
    QEMU 虚拟 aarch64(arm64) 记录
    DE-9IM 空间关系模型
  • 原文地址:https://www.cnblogs.com/tigerlion/p/11182844.html
Copyright © 2020-2023  润新知