Java20:反射

发布时间:2024年01月09日

第一个阶段
Java代码三个阶段01
第二个阶段
![Java代码三个阶段02第三个阶段

Java代码三个阶段03
反射-获取Class对象的三种方式:
反射-获取Class对象的三种方式

反射:框架设计的灵魂。

1. 概念

官方解释:反射是指在程序运行过程中,动态的获取类的信息,并且访问

我们通过反射还是获取类的信息(属性,方法,构造方法),然后访问,只不过我们现在不再以new的方式获取

反射的好处:

? 1、可以在程序运行过程中,操作这些对象

? 2、可以解耦,提高程序的可

Java中反射相关的API都位于java.lang.reflect包下

万物皆对象

Class 类

Method 方法

Filed 属性

Constructor 构造方

2. 获取成员变量

2.1 获取public修饰的成员变量

getFields() 获取所有的public修饰的属性/成员变量

? 操作:(1)设置值;(2)获取值

getField(String name)根据名字获取单个属性对象

package com.qfedu.test1;

import java.lang.reflect.Field;
/**
 * 	获取public声明的所有的属性信息 并且访问
 * @author WHD
 *
 */
public class Student {
	public String name;
	public int age;
	public String address;

	public Student() {
		System.out.println("Student类的无参构造");
	}

	public static void main(String[] args) {
		try {
			// 根据包名+ 类名 (全限定名)获取类信息文件
			Class<?> stuClass = Class.forName("com.qfedu.test1.Student");
			// 调用Class类的newInstance方法 构造实例
			Object newInstance1 = stuClass.newInstance();
			Object newInstance2 = stuClass.newInstance();
			Object newInstance3 = stuClass.newInstance();

			// 通过Class对象获取到当前类所有的属性 返回值为字段数组
			Field [] fs = stuClass.getFields();
			for(Field f : fs) {
				System.out.println(f.getName());
			}

			// 根据字段名称获取到单个字段对象
			Field nameField = stuClass.getField("name");

			// 调用字段set方法 设置属性值
			nameField.set(newInstance2, "赵四");

			// 调用字段get方法  获取属性值
			System.out.println(nameField.get(newInstance2));

			Field ageField = stuClass.getField("age");

			ageField.set(newInstance1, 20);
			System.out.println(ageField.get(newInstance1));

			Field addressField = stuClass.getField("address");
			addressField.set(newInstance3, "象牙山");
			System.out.println(addressField.get(newInstance3));


		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
	}

}

2.2 获取已声明的属性

getDeclaredFields() 获取所有已定义的属性对象 包括 private 默认 protected public

getDeclaredField(String name) 根据名字获取单个属性对象 可以是任意访问修饰符

package com.qfedu.test2;

import java.lang.reflect.Field;

/**
 * 	获取到类中所有的属性
 * @author WHD
 *
 */
public class Person {
	private String name;
	int age;
	protected String address;
	public char sex;
	
	public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
		Class<?> personClass = Class.forName("com.qfedu.test1.Person");
		Field[] fs = personClass.getDeclaredFields();
		for (Field field : fs) {
			System.out.println(field.getName() + "\t" +field.getType());
		}
		
		Object newInstance = personClass.newInstance();
		Field nameField = personClass.getDeclaredField("name");
		nameField.set(newInstance, "广坤");
			nameField.setAccessible(true);//暴力反射(不会报警告)
		System.out.println(nameField.get(newInstance));
		
		Field sexField = personClass.getDeclaredField("sex");
		sexField.set(newInstance, '男');
		System.out.println(sexField.get(newInstance));
		
	}
}
package com.qfedu.test2;
import java.lang.reflect.Field;
/**
 * 	获取属性
 * 	getFields() 获取所有的public修饰的属性
 * 	getField(String name)根据名字获取单个属性对象
 * 	getDeclaredFields() 获取所有已定义的属性对象。包括 private 默认 protected public
 * 	getDeclaredField(String name) 根据名字获取单个属性对象 可以是任意访问修饰符 
 * @author WHD
 *
 */
public class TestPerson {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InstantiationException {
//		Person p = new Person();
//		p.name = ""
		
		Class<?> personClass = Class.forName("com.qfedu.test1.Person");
		
		Field nameField = personClass.getDeclaredField("name");
		
		nameField.setAccessible(true); // 设置访问权限为true 表示忽略JVM非法访问异常
		
		
		
		System.out.println(nameField.getName() + nameField.getType());
		Object newInstance = personClass.newInstance();
		nameField.set(newInstance, "赵四");
		System.out.println(nameField.get(newInstance));
		
		
	}
}

3.获取方法

? 方法的三要素:方法名,返回值列表,参数值列表

? 确定一个方法的两要素:方法名,参数值列表

3.1 获取public修饰的,和继承自父类的 方法

getMethods() 获取本类所有public修饰的方法和继承父类的方法

getMethod() 获取单个的方法

package com.qfedu.test3;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TestStudent {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Class<?> studentClass = Class.forName("com.qfedu.test3.Student");
		Method[] methods = studentClass.getMethods();
		 System.out.println(methods.length);
		for (Method method : methods) {
			 System.out.println(method.getName());
		}
		Object newInstance = studentClass.newInstance();
		Method m1Method = studentClass.getMethod("m1");
		
		m1Method.invoke(newInstance);
		
		
		Method method = studentClass.getMethod("m1", String.class);
		method.invoke(newInstance, "赵四");
		
		
		Method method2 = studentClass.getMethod("m1", int.class);
		method2.invoke(newInstance, 330);
		
		
		Method method3 = studentClass.getMethod("m3", String.class,int.class);
		method3.invoke(newInstance, "赵四",22);
	}
}

3.2 获取本类中定义的方法

//获取单个本类中声明的方法。如果访问权限不足,可以使用此方法

getDeclaredMethod(String name,Class<?>…parameterTypes)

setAccessable(true);//暴力修改权限

getDeclaredMethods();// 获取所有本类中已定义的方法

package com.qfedu.test4;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TestStudent {
	public static void main(String[] args) {
		try {
			Class<?> stuClass = Class.forName("com.qfedu.test4.Student");
			Method[] ms = stuClass.getDeclaredMethods();
			for (Method method : ms) {
				System.out.println(method.getName());
			}
			Object newInstance = stuClass.newInstance();
			Method m1 = stuClass.getDeclaredMethod("m1");
			m1.setAccessible(true); // 私有方法必须设置访问权限为true
			m1.invoke(newInstance);
			
			
			Method m2 = stuClass.getDeclaredMethod("m1", String.class);
			m2.invoke(newInstance, "赵四");
			
			
			Method m3 = stuClass.getMethod("m3", String.class,int.class);
			m3.invoke(newInstance, "广坤",20);
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		}
	}
}

4. 获取构造器

4.1 获取所有public修饰的构造器

? constructor的作用:创建对象

getConstructors() 获取public修饰的构造方法

getConstructor(Class … type) 获取单个的构造器对象

package com.qfedu.test5;
/**
 * 	获取本类中定义的以public修饰的构造方法
 * @author WHD
 */
public class Student {
	public String name;
	public int age;
	public String address;

	public Student() {
		System.out.println("Student类的无参构造");
	}
    
	public Student(String name, int age, String address) {
		this.name = name;
		this.age = age;
		this.address = address;
		System.out.println("三个参数的构造方法");
	}
    
	public Student(String name) {
		this.name = name;
		System.out.println("一个参数的构造方法");
	}

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
		System.out.println("两个参数的构造方法");
	}
}
package com.qfedu.test5;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class TestStudent {
	public static void main(String[] args) {
		try {
			Class<?> stuClass = Class.forName("com.qfedu.test5.Student");
			Constructor<?>[] cs = stuClass.getConstructors();
			for (Constructor<?> c : cs) {
				System.out.println("名字" + c.getName() + "参数个数" + c.getParameterCount());
			}
			
			Constructor<?> constructor1 = stuClass.getConstructor();
			Object newInstance1 = constructor1.newInstance();
			
			
			Constructor<?> constructor2 = stuClass.getConstructor(String.class,int.class,String.class);
			Object newInstance2 = constructor2.newInstance("赵四",20,"象牙山");
			
			
			Constructor<?> constructor3 = stuClass.getConstructor(String.class);
			Object newInstance3 = constructor3.newInstance("广坤");
			
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
}

4.2 获取本类中定义的构造器

getDeclaredConstructors() 获取本类中定义的所有的构造方法

getDeclaredConstructor() 获取本类中单个的构造方法

package com.qfedu.test6;
/**
 * 	获取本类中定义的以public修饰的构造方法
 * @author WHD
 */
public class Student {
	public String name;
	public int age;
	public String address;
	private Student() {System.out.println("Student类的无参构造");}

	 Student(String name, int age, String address) {
		this.name = name;
		this.age = age;
		this.address = address;
		System.out.println("三个参数的构造方法");
	}

	protected Student(String name) {
		this.name = name;
		System.out.println("一个参数的构造方法");
	}

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
		System.out.println("两个参数的构造方法");
	}
}
package com.qfedu.test6;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class TestStudent {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
			Class<?> stuClass = Class.forName("com.qfedu.test6.Student");
			Constructor<?>[] cs = stuClass.getDeclaredConstructors();
			System.out.println(cs.length);
			
			
			Constructor<?> cons1 = stuClass.getDeclaredConstructor();
			cons1.setAccessible(true);
			Object newInstance1 = cons1.newInstance();
	}
}

5.jdk文件分析

5.1bin目录:

? 执行文件javac、javadoc、Javaws、jcmd、jconsole、jdb控制台、jsadebugd、keytool生成证书

5.2 include:底层用的是C++写的

? .h : C语言写的文件; win32 : 系统底层

5.3 jre:运行环境

5.4 lib : 包含jar包

? Java.long、java.applet用于处理图形、fonts字体设置、security安全、Java核心jar包:rt.jar

6、获取类名

method.getName();//获取方法名

*Class.getName();//获取类名

String className = studentClass.getName();

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