java --- 反射

2023-12-21 06:40:17

目录

一、什么是反射?

?二、获取 Class对象 的三种方式

三、反射获取构造方法(Constructor)

四、反射获取成员变量(Field)

五、反射获取成员方法(Method)


一、什么是反射?

  • 反射允许对成员变量,成员方法和构造方法的信息进行编程访问。
  • 反射就是把java类中的各种成分映射成一个个的Java对象

  • 例如:一个类有:成员变量、方法、构造方法等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。

提问:为什么不能用IO流从上往下一行一行的进行读取呢?

  • 但是当我们读取到构造方法和普通成员方法时,无法区分。
  • 成员变量和局部变量也很难区分。

因此我们使用?反射?获取成员变量就可以得到成员所有信息

?二、获取 Class对象 的三种方式

使用反射的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)

  1. ?Class.forName ( "?全类名?" ) ;? ? ? ? ? ? ?最为常用
  2. 类名 . class? ? ? ?一般更多的是当做参数进行传递
  3. 对象 . getClass ( ) ;??当已经有类对象是才能使用

//第一种方式
        Class cl1 = Class.forName("反射.Student");
        System.out.println(cl1);

        //第二种方式
        Class cl2 = Student.class;
        System.out.println(cl2);
        System.out.println(cl1 == cl2);

        //第三种方法
        Student s = new Student();
        Class cl3 = s.getClass();
        System.out.println(cl3);
        System.out.println(cl1 == cl3);

三、反射获取构造方法(Constructor)

Class类中获取构造方法的方法:

Constructor <?> [ ] getConstructors()返回所有公共构造方法对象的数组
Constructor <?> [ ] getDeclaredConstructors()返回所有构造方法对象的数组
Constructor <T> getConstructor ( Class <> .. parameterTypes )返回单个公共构造方法对象
Constructor <T> getDeclaredConstructor(Class <>.. parameterTypes)返回单个构造方法对象
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class cl1 = Class.forName("反射.Student");

        //利用反射获取构造方法
        Constructor[] con1 = cl1.getDeclaredConstructors();
        for (Constructor c : con1) {
            System.out.println(c);
        }
        Constructor con2 = cl1.getDeclaredConstructor(int.class);
        System.out.println(con2);

        //获取权限修饰符
        int modifiers = con2.getModifiers();
        //private :2 ,public:1 ,protected :4
        System.out.println(modifiers);

        //创建对象
        con2.setAccessible(true);//为了调用非public的方法,需要这样
        con2.newInstance(18);
    }

四、反射获取成员变量(Field)

Class类中获取成员变量的方法:

Field [ ]? getFields()返回所有公共成员变量对象的数组
Field [ ]? getDeclaredFields ( )返回所有成员变量对象的数组
Field getField ( String name )返回单个公共成员变量对象
Field getDeclaredField ( String name )返回单个成员变量对象

Field类中用于创建对象的方法:

void?set?( Object obj , Object value )赋值
Object?get?( Object obj )获取值
// 1.获取Class字节码文件的对象
		Class clazz = Class.forName("ReFlect.Student");
 
		// 获取成员变量
		//获取所有的成员变量
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			System.out.println(field);
			//private java.lang.String ReFlect.Student.name
			//private int ReFlect.Student.age
			//public java.lang.String ReFlect.Student.gender
		}
		
		//获取单个成员变量
		Field gender = clazz.getField("gender");
		System.out.println(gender);
		//public java.lang.String ReFlect.Student.gender
		
		//Field name = clazz.getField("name");  
		//无法获取 name是private私有的
		Field name = clazz.getDeclaredField("name"); 
		System.out.println(name);
		//private java.lang.String ReFlect.Student.name
		
		//获取到成员变量后我们可以继续:
		//1.获取权限修饰符
		int modifier = name.getModifiers();
		System.out.println(modifier);  //2
		//2.获取成员变量名
		String n = name.getName();
		System.out.println(n); //name
		//3.获取数据类型
		Class<?> type = name.getType();
		System.out.println(type); //class java.lang.String
		//4.获取成员变量记录的值
		Student s = new Student("张三",23,"男");
		name.setAccessible(true);
		Object value = (String)name.get(s);  //张三
		System.out.println(value);
		//5.修改成员变量记录的值
		name.set(s, "李四");
		System.out.println(s);  //Student [name=李四, age=23, gender=男]	
	}

五、反射获取成员方法(Method)

Class类中获取成员方法的方法:

Method [ ]? getMethods ( )返回所有公共成员方法对象的数组,包括继承的
Method [ ]? getDeclaredMethods ( )返回所有成员方法对象的数组,不包括继承的
Method getMethod ( String name ,? Cass <?> .. parameterTypes )返回单个公共成员方法对象
Method getDeclaredMethod ( String name ,? Class<?>... parameterTypes )返回单个成员方法对象

Method类中用于创建对象的方法:

Object?invoke?( Object obj ,? Object... args )运行方法

参数一:用obj对象调用该方法

参数二:调用方法的传递的参数(如果没有就不写)
返回值:方法的返回值(如果没有就不写)

public static void main(String[] args) throws 
           ClassNotFoundException, NoSuchFieldException {
 
		// 1.获取Class字节码文件的对象
		Class clazz = Class.forName("ReFlect.Student");
 
		// 2.获取里面所有的方法对象
		//(包含所有父类中的所有的公共方法)
		Method[] methods1 = clazz.getMethods();
		for(Method method : methods1) {
			System.out.println(method);
		}
		//获取里面所有的方法对象(只能获取本类中私有方法)
		Method[] methods2 = clazz.getDeclaredMethods();
		for(Method method : methods2) {
			System.out.println(method);
		}
		
		//3.获取指定单一方法对象
		Method m = clazz.getDeclaredMethod("eat", String.class);
		System.out.println(m); //private void ReFlect.Student.eat(java.lang.String)
		  //1.获取权限修饰符
		int modifers = m.getModifiers();
		System.out.println(modifers); //2
		//2.获取方法名
		String name = m.getName();
		System.out.println(name);  //eat
		//3.获取方法形参
		Parameter[] parameters = m.getParameters();
		for (Parameter parameter : parameters) {
		System.out.println(parameter);	 //java.lang.String arg0
		}
		//4.获取方法返回值
		//5.获取方法抛出异常
		Class<?>[] exceptionTypes = m.getExceptionTypes();
		for(Class exceptiontype : exceptionTypes) {
			System.out.println(exceptiontype);
			//class Java.io.TOException
			//class java. lang. NullPointerException
			//class java. lang.ClassCastException
 
		}
		
		//方法运行
		Student s = new Student();
		m.setAccessible(true);
		m.invoke(s, "汉堡包");
	}

文章来源:https://blog.csdn.net/flyingcloud6/article/details/135119493
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。