- 1.反射
- 1.1什么是反射?
- 1.2通过反射对对象进行 *** 作;
- 1.2.1通过反射加载类的三种方式;
- 1.2.2通过反射拿到类名,包名
- 1.2.3通过反射拿到属性,方法
- 1.2.4通过反射拿到构造方法,创建对象
- lambda表达式
把类的各个组成部分通过映射成为对象,然后通过对象再对类的各个部分进行 *** 作,这就是反射;
1.2通过反射对对象进行 *** 作; 1.2.1通过反射加载类的三种方式;package blue; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Reflect { public static void main(String[] args) throws ClassNotFoundException{ //1.使用Class.forName();方法; Class cls = Class.forName("blue.Student"); //2.使用类名.class 加载 Class cls2 = Student.class; System.out.println(cls2 == cls); //先创建对象,再通过对象名.getClass()方法加载; Student s = new Student(); Class cls3 = s.getClass(); System.out.println( cls3== cls); } }
三种方式加载的对象是同一个对象,第一种常用于配置文件中;第二种用于方法的参数当中;第三种用于有对象的时候,它是Object的方法,通过查看源码,它是一个native方法;
1.2.2通过反射拿到类名,包名System.out.println("...........类名"); System.out.println(cls.getName());//类的完全限定名 System.out.println(cls.getPackage());//拿到的是包对象; System.out.println(cls.getPackage().getName());//包名;1.2.3通过反射拿到属性,方法
Field[] field2 = cls.getFields(); System.out.println(field2.length); Field field = cls.getField("name"); System.out.println(field);
通过getField(“属性名”),getFields()方法,我们可以获取到单个属性,和属性数组,那为什么会报找不到异常呢,我们明明也有name属性,它也拿不到,获取的数组长度也为0呢;这是因为这两个方法有个条件就是,要获取的属性访问修饰符必须是public的,否则,没用
那我们偏偏就想要其他权限下的属性呢,当然了,我们的Java还给我们提供了另外的方法;
Field[] field3 = cls.getDeclaredFields(); Field field4 = cls.getDeclaredField("name"); for(Field field : field3) { System.out.println(field.getName()); } System.out.println(field4.getName());
当我们使用set或者get方法时,若没有使用setAccessible(true);就会报错: Class blue.Reflect can not access a member of class blue.Student with modifiers “private”
Class cls = Class.forName("blue.Student"); Student s = new Student(); s.setName("张三"); Field field4 = cls.getDeclaredField("name"); field4.setAccessible(true); field4.set(s, "小黑"); Object obj = field4.get(s); System.out.println(obj);
方法与属性相似但又有其他问题,GetMethods 返回包含继承的 public方法,而getDeclaredMethods()不包含继承的方法;
//Method m = cls.getMethod("getAge",String.class); //Method[] m1 = cls.getMethods();访问权限是public;获取的除了自己的还有继承的public方法; Method m2 = cls.getDeclaredMethod("getName", String.class);//添加类型.class,拿到重载方法; Method[] m3 = cls.getDeclaredMethods(); for(Method m4:m3) { System.out.println(m4);//m4.getName()获取方法名; }
Class cls = Class.forName("blue.Student"); Student s = new Student(); s.setName("小黑"); Method method0 = cls.getDeclaredMethod("setName",String.class); method0.invoke(s,"小红");//执行方法; Method method = cls.getDeclaredMethod("getName",String.class); method.setAccessible(true); Object obj = method.invoke(s,""); System.out.println(obj);1.2.4通过反射拿到构造方法,创建对象
Class cls = Class.forName("blue.Student"); Student s = new Student(); s.setName("小黑"); Constructor con = cls.getConstructor(String.class,String.class); System.out.println(con); //通过构造器实例化; Student student = (Student) con.newInstance("小猫","男"); System.out.println(student); //通过Class实例化,调用无参构造方法; Student ss = (Student) cls.newInstance(); System.out.println(ss); Constructor[] cons = cls.getConstructors(); for(Constructor c : cons) { System.out.println(c); }lambda表达式
。。。。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)