反射

反射的概述:

  • 是在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展。

获取Class类的对象

  • 我们想通过反射去使用一个类,首先我们要获取到该类的字节码文件对象,也就是类型为Class类型的对象。

  • 三种方式获取

    1. 使用class属性来获取该类对应的Class对象。

    2. 调用对象的getClass();返回该对象所属类对应的Class对象。该方法时Object类中的方法,所有的java对象都可以调用。

    3. 使用Class类中的静态方法forName(String className),该方法需要传入字符串参数,该字符串参数的值是某个类的全路径,也就是完整包名的路径。

1.反射获取构造方法,并创建对象

package com.yang.reflex;
//获取Class类的对象
public class ReflexDemo01 {
   public static void main(String[] args) throws ClassNotFoundException {

       //1种方法:使用class属性,类名.class
       Class<Student> c1 = Student.class;
       System.out.println(c1);

       System.out.println("--------");

       //2第二种 调用对象的getClass()方法 S.getClass();
       Student S = new Student();
       Class<? extends Student> c2 = S.getClass();
       System.out.println(c1==c2);

       System.out.println("--------");

       //第3种 使用Class类中的静态方法forName("完整包名的路径,即类的全路径")
       Class<?> c3 = Class.forName("com.yang.reflex.Student");//抛个异常
       System.out.println(c1==c3);


  }
}
package com.yang.reflex;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Demo02 {
   public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {

       Class<?> c = Class.forName("com.yang.reflex.Student");

       Constructor<?>[] cons = c.getConstructors();//获得公共的构造函数
       for (Constructor con : cons) {
           System.out.println(con);
      }
       System.out.println("--------");

       Constructor<?>[] dec = c.getDeclaredConstructors();
       for (Constructor con : dec) {
           System.out.println(con);
      }


       Constructor<?> c1 = c.getConstructor();//获得无参构造函数Constructor对象
       Object obj = c1.newInstance();//创建对象
       System.out.println(obj);

  }
}
2.
package com.yang.reflex;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

//用反射创建对象
public class Demo03 {
   public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
       //获得类对象
       Class<?> c = Class.forName("com.yang.reflex.Student");
       //遍历构造函数对象
       Constructor<?>[] c3 = c.getConstructors();
       for (Constructor c4 : c3) {
           System.out.println(c4);

      }
       System.out.println("----------");
       //获得三个的参数的构造函数
       Constructor<?> c2 = c.getConstructor(String.class, int.class, String.class);
       //创建对象
       Object obj = c2.newInstance("雷欧娜", 20, "北京");
       System.out.println(obj);
  }
}
package com.yang.reflex;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Demo04 {
   public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
       Class<?> c = Class.forName("com.yang.reflex.Student");
       //获得单个的私有的构造方法
       Constructor<?> dec = c.getDeclaredConstructor(String.class);
       //暴力访问
       dec.setAccessible(true);//true取消访问限制

       //.IllegalAccessException 非法访问,私有的不能直接创建对象。
       Object obj = dec.newInstance("林青霞");
       System.out.println(obj);

  }
}
package com.yang.reflex;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

//返射获取成员变量并使用
public class Demo05 {
   public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
       Class<?> c = Class.forName("com.yang.reflex.Student");
       //获取属性对象
       Field field = c.getField("address");
       //获无参构造方法
       Constructor<?> con = c.getConstructor();
       //获取对象
       Object obj = con.newInstance();
       //给对象obj的属性field赋值
       field.set(obj,"杭州");
       //输出
       System.out.println(obj);
       
  }
}
2.
package com.yang.reflex;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class Demo06 {
   public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
       //创建类的对象
       Class<?> c = Class.forName("com.yang.reflex.Student");
       //创建无参构造方法的对象
       Constructor<?> con = c.getConstructor();
       //创建对像实类
       Object obj = con.newInstance();
       //输出
       System.out.println(obj);

       //给属性赋值
       Field nameField = c.getDeclaredField("name");
       nameField.setAccessible(true);
       nameField.set(obj,"张无忌");
       System.out.println(obj);

       Field ageField = c.getDeclaredField("age");
       ageField.setAccessible(true);
       ageField.set(obj,20);
       System.out.println(obj);

       Field addressField = c.getDeclaredField("address");
       addressField.setAccessible(true);
       addressField.set(obj,"杭州");
       System.out.println(obj);

  }
}
   
package com.yang.reflex;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

//反射获取成员方法
public class Demo07 {
   public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
       //创建类的对象
       Class<?> c = Class.forName("com.yang.reflex.Student");
       //无参构造方法创建对象
       Constructor<?> con = c.getConstructor();
       //获取方法对象[无参,无返回值
       Method method = c.getMethod("method1");
       //创建对象实类
       Object obj = con.newInstance();
       //对象调方法:obj对象调用方法invoke  
       method.invoke(obj);
  }
}
2.
package com.yang.reflex;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Demo08 {
   public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
       //创建类的对象
       Class<?> c = Class.forName("com.yang.reflex.Student");
       //无参方法获取构造方法的对象
       Constructor<?> con = c.getConstructor();
       //创建对象
       Object obj = con.newInstance();
       //获取方法无参无返回值method2对象
       Method m1 = c.getMethod("method1");
       m1.invoke(obj);
       //获取有参的方法对象method2对象
       Method m2 = c.getMethod("method2", String.class);
       m2.invoke(obj,"张无忌");
       //获取有参有返回值的方法对象method3
       Method m3 = c.getMethod("method3", String.class, int.class);
       Object o = m3.invoke(obj, "西安", 20);
       System.out.println(o);
       //获取私有的方法对象fun
//       Method fun = c.getMethod("fun");//私有的这个获得的是公共的
       Method fun = c.getDeclaredMethod("fun");
       //暴力访问权限
       fun.setAccessible(true);
       fun.invoke(obj);
  }
}
   
package com.yang.reflex;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

public class Demo09 {
   public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
       ArrayList<Integer> array = new ArrayList<>();
//       array.add(20);
//       array.add(20);
//       array.add("hello");泛型检测

       //可以用反射越过泛型检测添加字符串
       //获得集合的对象
       Class<? extends ArrayList> a = array.getClass();
       //获得add方法对象
       Method add = a.getMethod("add", Object.class);
       //调方法,往集合中添加元素
//       add.invoke(a,"hello");
       add.invoke(array,"hello");
       add.invoke(array,"world");
       add.invoke(array,"java");

       System.out.println(array);

  }
}
package com.yang.reflex;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;

//配置文件读取
public class Demo10 {
   public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
       //读取加载文件
       Properties prop  = new Properties();
       FileReader reader = new FileReader("basicGrammar\\class.txt");
       prop.load(reader);
       reader.close();
       //读取配置文件
       String className = prop.getProperty("className");
       String classMethod = prop.getProperty("classMethod");

       //反射得到类对象
       Class<?> c = Class.forName(className);
       //创建构造方法对象
       Constructor<?> con = c.getConstructor();
       //创建对象
       Object obj = con.newInstance();
       //得到方法对象
       Method m1 = c.getMethod(classMethod);
       //调方法
       m1.invoke(obj);
  }
}

class.txt
className=com.yang.reflex.Student
classMethod=study