编程学习

Java高级——Java反射机制

2019-03-01  本文已影响0人  剑起长歌

一. 什么是反射?



二. 为什么要用反射机制?直接创建对象不就可以了吗? 这就涉及到了动态与静态的概念。


三.Java反射机制主要提供了一下功能:


四.Class对象:Class对象是Reflection的起源,想要操纵类中的属性和方法,都必须从获取Class对象开始。


获取Class对象的方法:

//创建一个类
class Person {

    private String name;

    public Person() {

    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
 public static void main(String[] args) {
      //通过 对象名.class 获取Class对象
      Person person = new Person();
      Class<?> personclass = person.getClass();
       System.out.println(personclass.getName());
  }
 public static void main(String[] args) {
      //通过 对象名.class 获取Class对象
      Person person = new Person();
      Class<?> personclass = person.getClass();
      System.out.println(personclass.getName());
      //获取personclass父类的Class
      Class<?> P_class = personclass.getSuperclass();
      System.out.println(P_class.getName());
  }
 public static void main(String[] args) {
      //通过 .class获取Class对象
       Class<?> personclass = Person.class;
       System.out.println(personclass.getName());
  }
  public static void main(String[] args) {
       //通过 Class.forName()获取Class对象
        Class<?> personclass = null;
       try {
           personclass = Class.forName("com.test.book.Person");
           System.out.println(personclass.getName());
       } catch (ClassNotFoundException e) {
           e.printStackTrace();
       }
   }
  public static void main(String[] args) {
       //通过 Primitive.TYPE获取基本类型的包装类的Class对象
        Class<?> intclass = Integer.TYPE;
        Class<?> doubleclass = Double.TYPE;
        
        System.out.println(intclass.getName());
        System.out.println(doubleclass.getName());
   }

五.java.lang.reflect库和Java反射常用API

Class类与java.lang.reflect类库一起对反射的概念进行支持。
java.lang.reflect包下:

通过反射机制实例化对象:

通过反射获取并调用方法:

通过反射获取并调用属性:

public class Employee{

    private String name;
    private int age;

    public Employee(){

    }

    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Employee{" + "name='" + name + '\'' + ", age=" + age + '}';
    }

    private void Work(){
        System.out.println("wroking...");
    }
}

通过反射机制构建一个Employee实例对象:

  public static void main(String [] args) throws Exception{
  //获取Employee类所关联的Class对象
    Class<?> employeeClass = Class.forName("book.ly.com.testjava.Employee");
    //通过Class.newInstance()构建Employee实例对象(默认调用无参数构造方法)
    Employee employee = (Employee) employeeClass.newInstance();
  }
  public static void main(String [] args) throws Exception{
  //获取Employee类所关联的Class对象
    Class<?> employeeClass = Class.forName("book.ly.com.testjava.Employee");
  //调用指定的构造方法构建Employee实例对象(无参数构造方法)
    Constructor<?> constructor  = employeeClass.getConstructor(new Class[]{});
    Employee employee = (Employee) constructor.newInstance(new Object[]{});
  }
  public static void main(String [] args){
  //获取Employee类所关联的Class对象
    Class<?> employeeClass = Class.forName("book.ly.com.testjava.Employee");
    Constructor<?> constructor  = employeeClass.getConstructor(new Class[]{String.class,int.class});
    Employee employee = (Employee) constructor.newInstance("张三",20);
  }

获取Class对象申明的方法并调用(包括私有的)

 public static void main(String [] args) throws Exception{
  //获取Employee类所关联的Class对象
    Class<?> employeeClass = Class.forName("book.ly.com.testjava.Employee");
    Constructor<?> constructor  = employeeClass.getConstructor(new Class[]{String.class,int.class});
    Employee employee = (Employee) constructor.newInstance("张三",20);
    
      //获取Class对象申明的所有方法(包括私有的)
     Method[] methods = employeeClass.getDeclaredMethods();
     for (Method method:methods){
     //打印方法的方法名 + 方法的修饰符(1-public,2-private...)
     System.out.println(method.getName() + "---" + method.getModifiers());
     }
     
    //获取Class对象指定的方法(包括私有的)
    Method method = employeeClass.getDeclaredMethod("toString",new Class[]{});
    //方法调用
    String str = (String)method.invoke(employee,new Object[]{});
    System.out.println(str);
    
    //调用私有方法
    Method method1 = employeeClass.getDeclaredMethod("Work");
    method1.setAccessible(true);//设置方法能被访问
    method1.invoke(employee);
}

获取Class对象申明的属性(包括私有的)

 public static void main(String [] args) throws Exception{
  //获取Employee类所关联的Class对象
    Class<?> employeeClass = Class.forName("book.ly.com.testjava.Employee");
    Constructor<?> constructor  = employeeClass.getConstructor(new Class[]{String.class,int.class});
    Employee employee = (Employee) constructor.newInstance("张三",20);
    
    //获取Class对象申明的所有属性(包括私有的)
    Field[] fields = employeeClass.getDeclaredFields();
    for (Field field:fields){
    //由于有私有的变量,我们设置为能被访问
    field.setAccessible(true);
    //打印获取到的属性的值
    System.out.println( field.get(employee));
    }
    
    //获取Class对象指定的属性(包括私有的)
    Field field = employeeClass.getDeclaredField("name");
    field.setAccessible(true);//设置为能被访问
    field.set(employee,"李四");//设置变量值
    System.out.println( field.get(employee));
  }

使用Java的反射机制创建数组:

 public static void main(String [] args) throws Exception{
        //创建一个一维数组(String)
        Class<?> tClass = Class.forName("java.lang.String");
        Object array = Array.newInstance(tClass, 5);//tClass 为数据类型的Class对象 5为数组长度
        //给array数组下标为 3 的元素赋值为“abc”
        Array.set(array,3,"abc");
        //取出array数组下标为 3 的值 并打印
        System.out.println(Array.get(array,3));

        //创建一个二维数组
        int [] dimens = {3,3};//3行  3列
        //创建一个int 类型 3行3列 的数组
        Object array2 = Array.newInstance(int.class,dimens);
        //给第二行 第二列 的元素赋值
        Object arrayobj = Array.get(array2,1);//获取第二行(一个一维数组)
        //给第二列赋值 (给获取的第二行的一维数组的第二个元素赋值)
        Array.set(arrayobj,1,10);
        int [] [] arr = (int[][]) array2;//强转为二维数组对象
        System.out.println(arr[1][1]);//取出第二行第二列的值并打印
  }

总结:

上一篇下一篇

猜你喜欢

热点阅读