Java8编程开发入门(47-反射机制)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/first52hz/article/details/82291092

目录

认识反射

实例化Class对象

反射实例化对象

在任何开发中,new是造成耦合的最大元凶

调用构造方法

调用普通方法

调用成员


认识反射

  • 概念:所谓的反,就是通过利用对象找到对象的出处
  • 类全名:java.lang.object
  • 方法:public final Class<?> getClass()
  • 使用:Date date = new Date(); System.out.println(date.getClass());

实例化Class对象

  • 概念:Class是反射的源头,所有的反射操作都要经过Class
  • 类全名:java.lang.Class
  • 方法:
  1. 调用object类中的getClass()     (用的较少)
  2. 使用类.class (此时并没有实例化对象产生,hibernate,mybatis,spring用的较多)
  3. 调用Class类的public static Class<?> forName(String name)方法 (此时不用导入包且没有实例化对象)
  • 使用:同上

反射实例化对象

  • 概念:通过Class类来实例化对象
  • 类全名:java.lang.Class
  • 方法:public T newInstance()   返回值可用Object类获取
  • 使用:Object obj = cls.newInstance(); Date date = (Date)obj;

在任何开发中,new是造成耦合的最大元凶

  • 概念:如果每增加一个水果类就要去修改工厂类,将导致工厂类要随时修改
  • 方法:public static Fruit getInstance()  { if() return new Apple(); }
  • 使用:Fruit f = null; f = (Fruit) Class.forName(name).newInstance();  //try catch块中  return f;

调用构造方法

  • 概念:当没有定义无参构造方法时却调用了newInstance()会导致抛出NoSuchMethodException异常
  • 类全名:java.lang.reflect.Constructor
  • 方法:先调用Class类的getConstructors()或getConstructor(Class<?> parameterType)方法获得Constructor<?> ,然后调用Constructor的public T newInstance(Object obj)方法实例化Object对象
  • 使用:Constuctor<?> con = cls.getConstructor(String.class,double.class); Object obj = con.newInstance("java",79);

调用普通方法

  • 概念:一个类调用普通方法必须要产生实例化对象后才可调用(三种实例化方法:new,clone,反射)
  • 类全名:java.lang.reflect.Method
  • 方法:先获得obj实例,再调用Class类的getMethods()或getMethod(String name,Class<?> parameterType)方法获得Method,然后调用Method的public Object invoke(Object obj,Object args)方法获得返回值(看不见Book类)
  • 使用:Object obj = cls.newInstance(); Method setMet = cls.getMethod("setName",String.class); setMet.invoke(obj,"java"); syso(getMet.invoke(obj));  (getMethod第一个参数可以写成set+init函数)
  • 注意:当forName不同包下的类时,如果该类不是public类,会导致IllegalAccessException

调用成员

  • 概念:类中的属性一定要在实例化对象后才可以分配内存空间
  • 类全名:java.lang.reflect.Field
  • 方法:先获得obj实例,再调用Class类的getDeclaredField(String name)获得Field,再调用Field的public Object get(Object obj)和public void set(Object obj,Object value)
  • 特殊:父类为AccessibleObject,且此类有两个子类Executable(继承了Constructor和Method)和Field,且AccessibleObject有一个方法为setAccessible(flag),取消封装(构造方法和普通方法同样可以使用)
  • 使用:实例化:Field nameField = cls.getDeclaredField("name"); nameField.setAccessble(true); nameField.set(obj,"java"); syso(nameField.get(obj));

猜你喜欢

转载自blog.csdn.net/first52hz/article/details/82291092