JAVA學習日記:反射機制(2)

2020-10-05 01:00:19

反射機制學習日記(2)

今天是之前學完的第二課:
Class類中的方法的使用(含程式碼和註釋):

getName()獲得全限定名稱(含包名)
getSimpleName()獲得類名(不含包名)
isPrimitive()判斷某個類是不是基本資料型別
isInterface()判斷Class範例是不是一個介面
isAnnotation()判斷Class範例是不是一個註解
isArray()判斷Class範例是不是一個陣列
isEnum()判斷當前呼叫的Class範例是不是一個列舉
getSuperclass()獲取當前範例物件的父類別
getInterfaces()獲得呼叫此方法的Class範例物件的所有介面
getModifier()獲取存取許可權修飾符,通常配合Modifer.toString來用
package LessonForReflection02;

import java.io.Serializable;
import java.lang.reflect.Modifier;

class person
{
	
}

abstract class Student extends person implements Serializable,Testable01,Testable02
{
	
}

public class GetClass 
{
	public static void main(String[] args) 
	{
		System.out.println("==============================");
		//以下是對本類做查詢
		System.out.println("以下是對本類做查詢");
		
		Class<Student> c1 = Student.class;//獲取一個.class方法獲得Student類的class範例
		
		//獲得全限定名稱
		System.out.println(c1.getName());
		//獲得類名沒有包名
		System.out.println(c1.getSimpleName());
		
		//得到一個類的package範例,獲取當前的包名
		System.out.println(c1.getPackage().getName());
		
		//判斷某一個class是不是代表一個基本資料型別
		System.out.println(c1.isPrimitive());
		
		//判斷它是不是一個介面
		System.out.println(c1.isInterface());
		
		//判斷它是不是一個註解
		System.out.println(c1.isAnnotation());
		
		//判斷它是不是一個陣列
		System.out.println(c1.isArray());
		
		//判斷它是不是一個列舉
		System.out.println(c1.isEnum());
		
		
		System.out.println("==============================");
		//以下是獲取父類別資訊
		//獲取本類的父類別,當前Student的父類別是Person
		System.out.println("獲取本類的父類別,當前Student的父類別是Person");
		
		Class<?> c2 = c1.getSuperclass();
		System.out.println(c2.getName());
		
		System.out.println("==============================");
		//以下是獲取介面型別
		//介面是返回一個class三陣列,因為可以接多個介面
		System.out.println("介面是返回一個class三陣列,因為可以接多個介面");
		
		Class<?>[] c3 = c1.getInterfaces();
		for (Class<?> c:c3)
		{
			System.out.println(c.getName());//Student類實現了3個介面
		}
		
		System.out.println("==============================");
		//獲取存取許可權修飾符
		System.out.println("獲取存取許可權修飾符");
		
		int mod1 = c1.getModifiers();//getModifiers()方法獲取到的許可權修飾符為整形
		String modifier = Modifier.toString(mod1);//Modifier類中的toString()方法可以把傳入的許可權修飾符整形形式裝換成字串形式
		System.out.println(modifier);//由於此時Student類前沒有任何修飾符所以此時輸出為空,我給他改成了abstract
		
		Class<GetClass> c4 = GetClass.class;
		int mod2 = c4.getModifiers();
		String modifierForGetClass = Modifier.toString(mod2);
		System.out.println(modifierForGetClass);
		
		System.out.println("==============================");
		//獲取JDK裡自涵的類的存取許可權修飾符
		System.out.println("獲取JDK裡自涵的類的存取許可權修飾符");
		
		int mod3 = Integer.class.getModifiers();
		String mod3f = Modifier.toString(mod3);
		System.out.println(mod3f);
		
		System.out.println("==============================");
		//獲取介面資訊修飾符資訊
		System.out.println("獲取介面資訊修飾符資訊");
		
		int mod4 = Serializable.class.getModifiers();
		String mod4f = Modifier.toString(mod4);
		System.out.println(mod4f);
		
		System.out.println("==============================");
		//JDK8.0之後提供的新方法.toGenertoGenericString()方法效果如下
		System.out.println("獲取介面資訊修飾符資訊");
		System.out.print(c1.toGenericString());
	}
}

Package類中常用的方法(含程式碼和註釋):

java.lang.Package:
	String getName()得到包名
	static Package getPackage(String name)得到指定的包
	static Package[] getPackage()得到當前開發環境下的所有包
package LessonForReflection02;

public class GetPackage 
{
	public static void main(String[] args) 
	{
		
		//1.
//		String getName();//得到包名
//		static Package getPackage(String name);//得到	指定包
		Package p1 = Package.getPackage("java.lang");//獲得到字串所對應的包的名字,封裝到P怕這個物件中去
		System.out.println(p1.getName());//得到包的名字
		
		//2.
//		static Package[] getPackage;//得到當前開發環境下的所有包
		Package[] p2 = Package.getPackages();
		for (Package p:p2)
		{
			System.out.println(p.getName());
		}
	}
}

Field類中的常用方法(含程式碼和註釋):

getFields()僅能獲取到本類及父類別介面中的public屬性,沒有申明許可權修飾符的屬性也是得不到的
getDeclaredFields()得到呼叫該方法物件的類中宣告過的屬性
package LessonForReflection02;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

interface Jumpable
{
	public static final int JUMPABLE_HIGH = 200;//常數
}

class Person01
{
	int person_age;
	public String person_name;
}

class Student01 extends Person01 implements Jumpable
{
	int student_score;
	public int student_age;
	private int speed;
	
}

public class FiledInfGeter 
{
	public static void main(String[] args) 
	{
		Class<Student01> c1 = Student01.class;
		
		//獲得Student類中可以用的public屬性
		//field用來封裝類裡面的域的
		Field[] stu_field1 = c1.getFields();//僅能獲取到本類及父類別和介面中的public屬性
		for (Field f1:stu_field1)
		{
			System.out.println(f1);
		}
		
		System.out.println("-----------------");
		
		Field[] stu_field2 = c1.getDeclaredFields();//得到呼叫該方法物件的類的宣告過的屬性!
		for (Field f2:stu_field2)
		{
			System.out.println(f2);
		}
		
		System.out.println("-----------------");
		
		try 
		{
//			Field f1 = c1.getField("speed");//私有的是得不到的
//			Field f2 = c1.getField("student_score");//沒有申明許可權修飾符的也沒有是得不到的
//			
//			int mod1 = f1.getModifiers();
//			System.out.println(Modifier.toString(mod1));
//			
//			int mod2 = f2.getModifiers();
//			System.out.println(Modifier.toString(mod2));
			
			Field f3 = c1.getField("student_age");//能夠獲得public屬性的修飾符
			int mod3 = f3.getModifiers();
			System.out.println(Modifier.toString(mod3));
		} catch (NoSuchFieldException | SecurityException e)//可以把平行的異常型別用|隔開寫在一起 
			{
				e.printStackTrace();
			}
		
		System.out.println("-----------------");
		
		//獲取person_name這個屬性的型別
		try 
		{
//			Field f5 = c1.getField("person_age");f5建立不了,person_age不是public型別
			Field f4 = c1.getField("person_name");//只能獲得到public型別的
			Class<?> type = f4.getType();
			System.out.println(type);
		} catch (NoSuchFieldException | SecurityException e) 
			{
				e.printStackTrace();
			}
	}
}

部分文字來源於:
咕嘟咖啡楊海濱老師 — 《java程式語言高階特性》
輕量化研習Java相關技術倡導者
「愛碼學院」聯合創始人自適應教學理念提出者踐行者;多年開發及專案管理經歷;出版《JavaEE企業級應用與開發》一書;10餘年高校專案實踐畢設指導經驗;企業軟培經驗豐富。