Logo

郎哥编程

使用反射技术实例化类

2021-07-16 274

学习目标:掌握实例化类的另外一种技术——反射技术。

在Java程序设计中,实例化类的方式一般是使用new运算符,new运算符会创建类的一个实例,类的实例也称为实例对象或对象,并返回创建的实例对象的引用。

类的实例化

案例1:分别建立Book类和BookManager类。Book类有bookName和bookAuthor属性;在BookManager类定义了loadBookWithNew()方法,该方法使用new运算符加载Book类,并创建Book类的实例对象,BookManager类的main()方法调用loadBookWithNew()方法实例化Book类。

新建项目PUnit13,在PUnit13项目新建reflex包,在reflex包下新建Book类。代码如下:

package reflex;
 
public class Book {
    // 图书名称
    private String bookName;
 
    // 图书作者
    private String bookAuthor;
 
    /**
     * 无参构造函数
     */
    public Book() {
        super();
    }
 
  
    public Book(String bookName, String bookAuthor) {
        super();
        this.bookName = bookName;
        this.bookAuthor = bookAuthor;
    }
 
    /**
     *
     * 重写父类的toString() 以字符串方式返回类信息
     */
    @Override
    public String toString() {
        return "Book [bookName=" + bookName + ", bookAuthor=" + bookAuthor + "]";
    }
 
    /**
     * 返回Book类的bookName属性
     */
    public String getBookName() {
        return bookName;
    }
 
    /**
     * @param 设置Book类的bookName属性
     */
    public void setBookName(String bookName) {
        this.bookName = bookName;
    }
 
    /**
     * 返回Book类的bookAuthor属性
     */
    public String getBookAuthor() {
        return bookAuthor;
    }
 
    /**
     * @param 设置Book类的bookAuthor属性
     */
    public void setBookAuthor(String bookAuthor) {
        this.bookAuthor = bookAuthor;
    }
 
 
}

Book类重写了父类的toString()方法,以字符串方式返回Book类的成员变量信息。

在reflex包下新建BookManager类。代码如下:

package reflex;
 
public class BookManager {
    public static void main(String[] args) {
        // 调用loadBookWithNew()方法
        loadBookWithNew();
 
    }
 
    /**
     * 使用new运算符实例化Book类
     */
    public static void loadBookWithNew()
    {
        Book tempBook = new Book();
        tempBook.setBookName("java技术深入理解");
        tempBook.setBookAuthor("编程训练营");
        //以字符串方式输出类信息
        System.out.println(tempBook.toString());
    }
 
 
}

当程序中需要实例化类时,常用方法是使用new运算符,new运算符是如何把类实例化为对象的呢?

Java类经过编译后会生成class文件,也就是字节码文件。如果该类没有加载到内存,new运算符会调用类加载器(ClassLoader)来加载类到内存,类加载器根据new传入的类名称在运行的Java程序路径中查找要加载的类,如果找到与该类名称相对应的字节码文件,类加载器会把类的字节码文件读入内存,并创建一个java.lang.Class对象(Class对象是该类所有实例化对象在内存中的代理)。如果该类有父类,类加载器也会把父类加载到内存中。类加载器完成类的加载任务后,new会完成类加载的后续工作,最后返回实例化对象的引用给对象变量。

对象变量会调用类提供的方法执行类提供的功能,获取或设置类的属性。例如:在前面案例代码BookManager类的loadBookWithNew方法中,实例化的类对象tempBook会调用Book类提供的set方法来设置Book类的属性,同时调用Book类的toString()方法以字符串方式获取类的信息,类的这些属性和方法在代码编译之前是必须要确定的。如果用new加载类后,类缺少这些方法和属性,编译器就会报错。因此new加载类属于静态加载,要接受编译器的检查。

反射技术

另外一种实例化对象的方式,就需要用到Java语言的反射机制。在本课内容中,先不具体介绍反射机制的工作原理及构成。先用反射技术来实例化对象,对反射有感性认识后,再具体介绍反射的工作原理及构成。

案例2:建立BookManager1类,该类定义loadBookWithRelflect()方法,该方法用反射来实例化类,可以实现和案例1方法loadBookWithNew()方法同样的效果。

在reflex包下新建BookManager1类。代码如下:

package reflex;
 
public class BookManager1 {
 
    public static void main(String[] args) {
        // 调用loadBookWithRelflect()方法
        loadBookWithRelflect();
 
    }
    public static void loadBookWithRelflect() {
        try {
            Class<?> classBook = Class.forName("reflex.Book");
            Object objectBook = classBook.newInstance();
            Book tempBook = (Book) objectBook;
            tempBook.setBookName("java核心技术课程");
            tempBook.setBookAuthor("编程训练营");
            System.out.println(tempBook.toString());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
 
    }
 
}

ookManager1类的loadBookWithRelflect()方法,利用Class.forName()方法加载Book类并返回Class对象(Class类会在下一课学习),然后调用Class对象的newInstance()方法实例化Book类,因为newInstance()方法返回Object类型,因此需要将返回的类型显示转换为Book类型。

从上面的执行结果可以看出,实例化类对象时,除了使用new运算符外,还可以使用Class对象的forName和newInstance()方法来实例化类对象。

代码在线纠错(通义千问 qwen-max)

支持粘贴多个代码文件,提交后由阿里云通义千问自动分析代码漏洞、语法错误、逻辑问题并给出修改建议。
您已解锁 AI 代码纠错功能,可正常使用!

评论区

登录 后发表评论
暂无评论