反射(反射的概念、反射的使用、Class类的其他方法)

一、反射的概念

通过某种机制,动态得到这个类所有信息(属性,方法,构造方法...), 也可以动态的调用这个类所有的属性,方法,构造方法... 这种机制就是所谓的反射

反射的核心: 类的镜子, 类的字节码文件 对应的类: Class类

每一个类, 它的Class类的对象, 唯一一个, 类的Class对象, 在这个类的字节码文件加载到内存时候,JVM就会为该类的字节码文件创建一个Class对象

二、反射的使用

1.得到某个类的Class对象

(1)类名.class 得到该类的Class对象

//第一种方式: 类名.classClass clazz = Student.class;

(2)类的对象.getClass()

//第二种方式: 类的对象.getClass()Student stu = new Student();//Student本类, 子类 上界Class clazz2 = stu.getClass();

(3)通过Class类的static方法: forName(类的全限定名); 类的全限定名: 包名.类名

//第三种: 通过Class类的static方法: forName(类的全限定名)Class clazz3  = Class.forName("com.fs.Student");
//得到的同一个对象System.out.println(clazz == clazz2);//trueSystem.out.println(clazz == clazz3);//true

2.通过Class对象获取某个类所有的属性,方法,构造方法,并使用和调用它

(1)获取属性

 //1.得到反射的核心对象: Class
Class clazz = Class.forName("com.fs.Student");//2.得到属性//1.根据属性名获取公开属性// 抛出NoSuchFieldException异常: 没有匹配的属性
Field nameFiled = clazz.getField("name");//打印属性名  getName()
System.out.println("属性名:"+nameFiled.getName());
System.out.println("访问修饰符:"+nameFiled.getModifiers());
System.out.println("属性数据类型:"+nameFiled.getType());//给属性赋值  set()
​//获取属性的值 get()*/
​//根据属性名获取属性, 不管是私有还是公开
Field nameFiled = clazz.getDeclaredField("name");//打印属性名  getName()
System.out.println("属性名:"+nameFiled.getName());// 0: 缺省的  1: public   2: private  4:protected
System.out.println("访问修饰符:"+nameFiled.getModifiers());
System.out.println("属性数据类型:"+nameFiled.getType());
​//给属性赋值 set(Object obj, Object value)//obj: 对象    value: 属性值
Student stu = (Student)clazz.newInstance();//给stu对象的name属性赋"王五"的值//设置private允许访问
nameFiled.setAccessible(true);
nameFiled.set(stu,"王五"); //底层: stu.name ="王五"
​
System.out.println(stu);
​//获取属性的值 Object get(Object obj)  //底层: stu.name
System.out.println("属性值:"+nameFiled.get(stu));System.out.println("==============================");//获取所有的属性Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {System.out.println("属性名:"+field.getName());}
       

(2)获取方法

 //1.得到反射的核心对象: Class
Class clazz = Class.forName("com.fs.Student");//2.获取公开的方法//根据方法名获取指定方法名的方法//NoSuchMethodException: 没有匹配的方法/*Method studyMethod = clazz.getMethod("study");
System.out.println("方法名:"+studyMethod.getName());
System.out.println("返回值类型:"+studyMethod.getReturnType());
System.out.println("参数列表类型:"+studyMethod.getParameterTypes());
System.out.println("参数个数:"+studyMethod.getParameterCount());
System.out.println("访问修饰符:"+studyMethod.getModifiers());*/
​//获取所有的公开方法,包括从父辈类继承Method[] methods = clazz.getMethods();for (Method method : methods) {System.out.println(method);}
​//回获取所有访问修饰符修饰的方法,Method[] methods = clazz.getDeclaredMethods();for (Method method : methods) {System.out.println(method);}Method studyMethod = clazz.getDeclaredMethod("study");
​//创建Student对象Student stu = (Student)clazz.newInstance();studyMethod.setAccessible(true);Object rs =  studyMethod.invoke(stu);System.out.println(rs);

(3)获取构造方法

 //1.得到该类Class对象
Class clazz = Student.class;
​//2.得到公开的构造方法//指定参数类型的构造方法// NoSuchMethodException异常: 没有匹配的方法的异常
Constructor c1 = clazz.getConstructor(int.class);//打印//getName() 得到方法名
System.out.println(c1.getName());//getModifiers() 访问修饰符
System.out.println(c1.getModifiers());*/
​//得到所有的公开的构造方法
Constructor[] constructors = clazz.getConstructors();for (Constructor constructor : constructors) {System.out.println(constructor);}
​//得到所有的 不管是公开还是私有
Constructor c1 = clazz.getDeclaredConstructor(int.class,String.class);//打印//getName() 得到方法名
System.out.println(c1.getName());//getModifiers() 访问修饰符   1 public  2 private
System.out.println(c1.getModifiers());
​
Constructor[] constructors = clazz.getDeclaredConstructors();for (Constructor constructor : constructors) {System.out.println(constructor);}//创建类对象//1.调用Class的newInstance() 调用公开的无参构造//IllegalAccessException 无法访问的异常: 无参构造方法是private修饰Student stu =  clazz.newInstance();   // new Student()System.out.println(stu);
​//2.私有Constructor的newInstance()方法Constructor c1 = clazz.getDeclaredConstructor(int.class,String.class);Student  stu2  = c1.newInstance(1, "张三");System.out.println(stu2);
​//如果构造方法是private修饰的Constructor c2 = clazz.getDeclaredConstructor(int.class);//如果是private修饰,默认无法访问.//可以设置允许访问private的  setAccessible(true)c2.setAccessible(true);Student  stu3  = c2.newInstance(1);System.out.println(stu3);

三、Class类的其他方法:

关于注解的相关的方法:

判断 元素上是否包含某个注解: Class,Filed,Method...

// boolean isAnnotation() 如果此 类对象表示注释类型,则返回true。

获取元素上的注解 Class,Filed,Method...

getAnnotation()

Class:

getName() 获取的全限定名: 包名.类名

getSimpleName() 获取的简单名: 类名

反射: 动态操作类的方法,属性,创建对象.... 框架底层使用

如果创建对象, 确定的类, 使用 new 构造方法()


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部