框架:半成品軟件,可以在框架的基礎上進行軟件開發,簡化編碼
反射:將類的各個組成部分封裝爲其他對象,這就是反射機制
好處:
* 可以在程序運行過程中,操作這些對象。
* 可以解耦,提高程序的可擴展性。
一、基本概念
在反射機制中,還可以通過反射得到一個類的完整結構,這就需要使用 java.lang.reflect 包中的以下幾個類:
Constructor:表示類中的構造方法
Field:表示類中的屬性
Method:表示類中的方法
這三個類都是 AccessibleObject 類的子類:
interface China{
public static final String NATIONAL = "China";
public static final String AUTHOR = "Java";
public void sayChina();//定義無參的抽象方法
public String sayHello(String name,int age);//定義有參的抽象方法
}
class Person implements China{
private String name;
private int age;
public Person(){
}
public Person(String name){//聲明有一個參數的構造方法
this.name = name;
}
public Person(String name,int age){
this(name);
this.setAge(age);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public void sayChina() {
System.out.println("作者:" + AUTHOR + ",國籍:" + NATIONAL);
}
@Override
public String sayHello(String name, int age) {
return name + "你好!我今年" + age + "歲了!";
}
}
二、取得所實現的全部接口
要取得一個類所實現的全部接口,必須使用 Class 類中的 getInterfaces() 方法,該方法定義:
public Class[] getInterfaces()
getInterfaces() 方法返回一個 Class 類的對象數組,之後直接利用 Class 類中的 getName() 方法輸出即可。
public class Root{
public static void main(String[] args) {
Class<?> c1 = null;//聲明 Class對象
try{
c1 = Class.forName("Person");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
Class<?> c[] = c1.getInterfaces();//取得實現的全部接口
for (int i=0;i<c.length;i++){
System.out.println("實現的接口名稱:" + c[i].getName());//輸出接口名稱
}
}
}
因爲接口是類的特殊形式,而且一個類可以實現多個接口,所以此時以 Class 數組的形式將全部的接口對象返回,並利用循環的方式將內容依次輸出
三、取得父類
一個類可以實現多個接口,但是隻能繼承一個父類,所以要想取得一個類的父類,可以直接使用 Class 類中的 getSuperclass() 方法,該方法定義:
public Class<? super T> getSuperclass()
getSuperclass() 方法返回的是 Class 實例,和之前得到的接口一樣,可以通過 getName() 方法取得名稱。
public class Test{
public static void main(String[] args) {
Class<?> c1 = null;
try {
c1 = Class.forName("Person");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
Class<?> c2 = c1.getSuperclass();//取得父類信息
System.out.println("父類名稱:" + c2.getName());
}
}
Person 類在編寫時沒有明確地繼承一個父類,所以默認繼承 Object 類
四、取得全部構造方法
要取得一個類中的全部構造方法,必須使用 Class 類中的 getConstructors() 方法。
1.取得 Person 類的全部構造方法
import java.lang.reflect.Constructor;
public class Test{
public static void main(String[] args) {
Class<?> c1 = null;
try {
c1 = Class.forName("Person");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
Constructor<?> con[] = c1.getConstructors();//得到全部構造方法
for (int i=0;i<con.length;i++){
System.out.println("構造方法:" + con[i]);
}
}
}
2.取得一個類的全部構造方法
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
public class Test{
public static void main(String[] args) {
Class<?> c1 = null;
try {
c1 = Class.forName("Person");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
Constructor<?> con[] = c1.getConstructors();//得到全部構造方法
for (int i=0;i<con.length;i++){
Class<?> p[] = con[i].getParameterTypes();//列出構造中的參數類型
System.out.print("構造方法:");
int mo = con[i].getModifiers();//取出權限
System.out.print(Modifier.toString(mo) + " ");//還原權限
System.out.print(con[i].getName());//輸出構造方法名稱
System.out.print("(");
for (int j=0;j<p.length;j++){
System.out.print(p[j].getName() + " arg" + i);
if (j<p.length-1){//打印參數類型,判斷是否要輸出“,”
System.out.print(",");
}
}
System.out.println("){}");
}
}
}
五、取得全部方法
要取得一個類中的全部方法,可以使用 Class 類中的 getMethods() 方法,該方法返回一個 Method 類的對象數組。該方法的常用方法:
取得一個類的全部方法定義:
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Test{
public static void main(String[] args) {
Class<?> c1 = null;
try {
c1 = Class.forName("Person");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
Method m[] = c1.getMethods();//取得全部的方法
for (int i=0;i<m.length;i++){
Class<?> r = m[i].getReturnType();//取出方法的返回值類型
Class<?> p[] = m[i].getParameterTypes();//得到全部的參數類型
int xx = m[i].getModifiers();//得到方法的修飾符
System.out.print(Modifier.toString(xx) + " ");//還原修飾符
System.out.print(r.getName() + " ");//得到方法名稱
System.out.print(m[i].getName());//取得方法名稱
System.out.print("(");
for (int x=0;x<p.length;x++){
System.out.print(p[x].getName() + " " + "arg" + x);//輸出參數
if (x<p.length-1){
System.out.print(",");//判斷是否輸出","
}
}
Class<?> ex[] = m[i].getExceptionTypes();//得到全部的異常拋出
if (ex.length>0){
System.out.print(") throws ");//輸出“) throws”
}else {
System.out.print(")");
}
for (int j=0;j<ex.length;j++){
System.out.print(ex[j].getName());//輸出異常信息
if (j<ex.length-1){
System.out.print(",");
}
}
System.out.println();
}
}
}
開發工具就是利用了反射的原理
六、取得全部屬性
在反射操作中也同樣可以取得一個類中的全部屬性,有兩種不同的操作:
得到實現的接口或父類中的公共屬性:public Field[] getFields() throws SecurityException
得到本類中的全部屬性:public Field[] getDeclareDeclaredFields() throws SecurityException
上述方法返回的都是 Field 的數組,每一個 Field 對象表示類中的一個屬性,而要想取得屬性的進一步信息,需要使用:
取得 Person 類中的屬性
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class Test{
public static void main(String[] args) {
Class<?> c1 = null;
try {
c1 = Class.forName("Person");
}catch (ClassNotFoundException e){
e.printStackTrace();
}
{//普通代碼塊
Field f[] = c1.getDeclaredFields();//取得本類屬性
for (int i=0;i<f.length;i++){
Class<?> r = f[i].getType();//取得屬性的類型
int mo = f[i].getModifiers();//得到修飾符數字
String priv = Modifier.toString(mo);//取得屬性的修飾符
System.out.print("本類屬性:");
System.out.print(priv + " ");//輸出修飾符
System.out.print(r.getName() + " ");//輸出屬性類型
System.out.print(f[i].getName());//輸出屬性名稱
System.out.println(";");//換行
}
}
System.out.println("===========================");
{
Field f[] = c1.getFields();//取得父類公共屬性
for (int i=0;i<f.length;i++){
Class<?> r = f[i].getType();//取得屬性的類型
int mo = f[i].getModifiers();//取得修飾符數字
String priv = Modifier.toString(mo);//取得屬性修飾符
System.out.print("公共屬性:");
System.out.print(priv + " ");//輸出修飾符
System.out.print(r.getName() + " ");//輸出參數類型
System.out.print(f[i].getName());//輸出屬性名稱
System.out.println(";");
}
}
}
}
作者:南淮北安
鏈接:https://juejin.cn/post/6923479418119651342
來源:掘金