00024.06 反射:反射的應用2:動態建立物件

平凡加班狗發表於2020-11-23

系列文章目錄

前言

怎麼建立物件?首先得先獲取Class物件才能建立物件

一、在執行時建立任意引用資料型別的物件

方式一:使用Class物件直接new物件
怎麼建立物件?首先得先獲取Class物件才能建立物件
(1)獲取某個型別的Class物件

(2)通過Class物件來建立這個Class所代表的型別的物件

在這裡插入圖片描述
在這裡插入圖片描述

方式二:通過Class物件先獲取有參構造,然後再建立物件
(1)獲取某個型別的Class物件
(2)通過Class物件來獲取Constructor物件

(2)通過Constructor物件來建立這個Class所代表的型別的物件

說明
(1)Constructor clazz.getConstructor(Class<?>… parameterTypes)某個公共的構造器
(2)Constructor clazz.getDeclaredConstructor(Class<?>… parameterTypes)某個宣告的構造器
一個類中可能存在多個構造器,但是多個構造器過載的話,形參列表一定不一樣,所以通過形參列表就可以唯一的定位到一個構造器
如果Class<?>… parameterTypes,一個都不傳,即獲取無參構造

在這裡插入圖片描述

二、完整程式碼

package com.atguigu.test07;

import java.lang.reflect.Constructor;

import org.junit.Test;

import com.atguigu.ext.demo.AtGuiguDemo;

/*
 * 2、在執行時能夠建立任意引用資料型別的物件
 * 
 * 方式一:使用Class物件直接new物件
 * 步驟:
 * (1)獲取某個型別的Class物件
 * (2)通過Class物件來建立這個Class所代表的型別的物件
 * 
 * 當AtGuiguDemo沒有無參構造時
 * java.lang.InstantiationException: com.atguigu.ext.demo.AtGuiguDemo
 * Caused by: java.lang.NoSuchMethodException: com.atguigu.ext.demo.AtGuiguDemo.<init>()
 * 
 *
 * 方式二:通過Class物件先獲取有參構造,然後再建立物件
 * 步驟:
 * (1)獲取某個型別的Class物件
 * (2)通過Class物件來獲取Constructor物件
 * (2)通過Constructor物件來建立這個Class所代表的型別的物件
 */
public class TestNewInstance {
	
	@Test
	public void test03(){
//		AtGuiguDemo s = new AtGuiguDemo(2,"xx",20);//The constructor AtGuiguDemo(int, String, int) is not visible
//		System.out.println(s);
	}
	
	@Test
	public void test02() throws Exception{
		//(1)獲取某個型別的Class物件
		Class clazz = Class.forName("com.atguigu.ext.demo.AtGuiguDemo");
				
		/*
		 * (1)Constructor clazz.getConstructor(Class<?>... parameterTypes)某個公共的構造器
		 * (2)Constructor clazz.getDeclaredConstructor(Class<?>... parameterTypes)某個宣告的構造器
		 * 一個類中可能存在多個構造器,但是多個構造器過載的話,形參列表一定不一樣,所以通過形參列表就可以唯一的定位到一個構造器
		 * 如果Class<?>... parameterTypes,一個都不傳,即獲取無參構造
		 */
		//(2)獲取有參構造物件
		Constructor c = clazz.getDeclaredConstructor(int.class,String.class,int.class);
		
		c.setAccessible(true);
		
		//(3)通過Constructor物件來建立例項物件
		Object obj = c.newInstance(1,"尚矽谷",10);//這裡的newInstance(實參列表),因為它用有參構造建立物件
		System.out.println(obj);
	}
	
	@Test
	public void test01() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
		//(1)獲取某個型別的Class物件
		Class clazz = Class.forName("com.atguigu.ext.demo.AtGuiguDemo");
		
		//(2)建立物件
		//obj的編譯時型別,Object型別
		//obj的執行時型別是AtGuiguDemo型別
		Object obj = clazz.newInstance();//這裡的newInstance()沒有引數,因為它是用無參構造建立例項
		System.out.println(obj);
	}
}

總結

相關文章