2019-04-16

2019-04-16  本文已影响0人  凨茗

Java使用反射机制生成对象的3种方式

一、在构造函数为空的情况下

普通对象Book,构造函数为空的情况下

Class Book{
    public Book(){
    System.out.println("初始化Book,无参构造函数!");
    }
  @Override
  public String toString(){
    System.out.println("这是一本书!“);
  }
}

1.使用对象的getClass方法

public class TestBook{  //测试方法
  public static void main(String[] args) throws Exception{
    Book b = new Book();
    Class<?> cls = b.getClass();
    Object obj = cls.newInstance();         //进行实例化
    Book book = (Book)obj;
    System.out.println(book);
  }
}

2.使用"类.class"取得

public class TestBook{  //测试方法
  public static void main(String[] args) throws Exception{
    Class<?> cls = Book.Class;
    Object obj = cls.newInstance();
    Book book = (Book)obj;
    System.out.println(book);
  }
}

3.调用Class对象提供的方法Class.forname

public class TestBook{  //测试方法
  public static void main(String[] args) throws Exception{
    Class<?> cls = Class.forName("Book");
    Object obj = cls.newInstance();
    Book book = (Book)obj;
    System.out.println(book);
  }
}

此时可以不使用import导入一个明确的类,可以使用字符串的方式进行描述

二、在构造函数不为空的情况下

普通对象Book,构造函数不为空的情况下

Class Book{
    private Stirng title ; 
    String double price;
    
    public Book(String title ,double price){
    this.title = title ; 
    this.price = price ;
    }
  @Override
  public String toString(){
    System.out.println("图书:“+this.title+ ",价格:"+this.price);
  }
}

此时不能直接调用getInstance 方法进行实例化,需要使用getConstructor方法,返回的是Constructor对象

具体如下

public class TestBook{
  public static void main(String[] args){
    Class<?> cls = Class.forName("Book");
    Construcotr<?> con = cls.getConstructor(String.class,double.class);//参数的类型定位
    Object obj = con.newInstance("Hadoop",49.9);  //里面是构造函数的参数
    System.out.println(obj); 
  }
}

所以最好在类中提供无参构造方法最好

三、反射调用方法

基本的对象Book

Class Book{
    private String title;
    public void setTitle(String title)(){
    this.tile=title;
    }
    public String getTitle(){
    return title;
    }
}

在Class类中有以下几种取得类中方法的操作

以上方法返回的java.reflect.Method类的对象,在这个类中重点关注一个方法

反射调用

import java.lang.reflect.Method;
public class TestBook{  //测试方法
  public static void main(String[] args) throws Exception{
    Class<?> cls = Class.forName("Book");
    Object obj = cls.newInstance(); //必须实例化对象才能调用方法
    Method  setMet= cls.getMethod("setTitle",String.class);
    Method  getMet= cls.getMethod("getTitle");
    setMet.invoke(obj,"java开发"); //等价于:Book类对象.setTitle(“java开发”)
    System.out.println(getMet.invoke(obj));
  }
}

四.反射调用成员

类中的属性一定要在本类实例化对象产生之后才能分配内存空间。在class类里面提供有取得成员的方法:

返回的类型java.lang.reflect.Field类,在这两个类中有两个重要的方法

基本对象Book

Class Book{
    public Book(){
        private String title;
  }
}

取得对象和设置对象

import java.lang.reflect.Field;
public class TestBook{  //测试方法
  public static void main(String[] args) throws Exception{
    Class<?> cls = Class.forName("Book");
    Object obj = cls.newInstance(); //必须实例化对象才能调用方法
    Field titleField = cls.getDeclaredField("title");
    titleField.set(obj,"java开发");//相当于:Book.title="java开发"
    System.out.println(titleField.get(obj))
  }
}

此时会提示错误,因为title是私有的属性

在java.lang.reflect.AccessibleObject类下面(jdk1.8之后修改)

上一篇下一篇

猜你喜欢

热点阅读