知识点:java中的反射
参考博客:https://www.cnblogs.com/tech-bird/p/3525336.html
一:概述
Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期间借助于Reflection ApI取得类的内部的信息,并能直接操作任意对象内部的属性和方法
Java反射机制主要提供的功能:
a.在运行时获取任意一个类所具有成员变量、方法、构造器、父类、内部类等等
b.在运行时创建任意类的对象
c.在运行时,调用任意一个对象的属性,方法等
d.生成动态代理(博客)
二:获取Class实例的几种方式
Person.class类
public class Person extends Animals<String> implements Comparable{
public String name;
private int age;
int id;
public Person(){
System.out.println("无参构造器");
}
public Person(String name){
System.out.println("有参构造器:"+name);
}
public void showInfo(){
System.out.println("调用public修饰的方法");
}
public void showInfo1(String name){
System.out.println("展示对象的属性方法——有参数:"+name);
}
public static void showInfo2(){
System.out.println("调用静态方法");
}
private void showInfo3(){
System.out.println("调用private修饰的方法");
}
public void drink(){
System.out.println("喝水!");
}
@Override
public String toString() {
return "id"+this.id+"name:"+this.name+"age:"+age;
}
@Override
public int compareTo(Object o) {
return 0;
}
}
//获取Class实例的几种方式
public class TestReflection1 {
public static void main(String[] args) throws ClassNotFoundException {
//1.运行时类的对象获取,通过对象获得Class实例
Person p=new Person();
Class c1=p.getClass();
System.out.println(c1.getName());
//2.调用运行时类本身(.class属性)
Class c2=Person.class;
System.out.println(c2.getName());
//3.通过Class的静态方法className获取
String className="com.kdgc.reflectiondemo.Person";//动态传入className
Class c3= Class.forName(className);
System.out.println(c3.getName());
//4.通过类加载器
//ClassLoader classLoader=this.getClass().getClassLoader();
//Class c4= classLoader.loadClass(className);
}
}
三:获取Class实例对应对象的属性、方法、构造器
//获取指定的属性,方法,构造器
public class TestReflectionAppointProperty {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
//(1)获取指定的属性
Class c=Person.class;
//1.反射调用运行时类的指定属性
//getField(String fileName):获取运行时类中声明为public的指定属性
Field name=c.getField("name");
//2.创建c对应运行时Person类的对象p
Person p=(Person) c.newInstance();
System.out.println(p);
//3.给运行时类的对象指定属性赋值
name.set(p,"张三");
System.out.println(p);
// Field age=c.getField("age"); age的修饰符是private
//getDeclaredField():获取运行时类中声明的指定属性
Field age=c.getDeclaredField("age");
//由于访问修饰符的限制,为了保证给属性成功赋值,需要操作前使得该属性可被操作
age.setAccessible(true);
age.set(p,21);
System.out.println(p);
Field id=c.getDeclaredField("id");//id是默认的权限修饰符,这里是可以正常获取的,如果报访问权限异常,设置setAccessible(true)
// age.setAccessible(true);
id.set(p,1001);
System.out.println(p);
//(2)获取指定的方法
//getMethod(String methodName,Class ...params):获取运行时类中声明为public的方法
Method m=c.getMethod("showInfo");
// m.setAccessible(true); 不行
//调用指定的方法 invoke(Object obj,args)
m.invoke(p);
//调用有参数的成员方法
Method m1=c.getMethod("showInfo1",String.class);
m1.invoke(p,"实参名字");
//运行时类中得静态方法的调用
Method m2=c.getMethod("showInfo2");
m2.invoke(Person.class);//直接传入对应的类,调用相应的方法
//getDeclaredMethod(String fileName,...paras):调用运行时类中,声明了的方法
Method m3=c.getDeclaredMethod("showInfo3");
m3.setAccessible(true);
m3.invoke(p);
//调用指定的构造器(有参),创建运行时类的对象
Constructor cons= c.getDeclaredConstructor(String.class);
cons.setAccessible(true);
cons.newInstance("构造器参数");
}
}