- 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表达式
。。。。



