反射(反射的概念、反射的使用、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 构造方法()
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
