一、定義注解
使用前提:使用@interface來進行宣告,會自動繼承 java.lang.annotation.Annotation介面注解中的每一個方法實際上是宣告了一個配置引數,方法的名稱就是引數的名稱,回傳值的型別就是引數的型別,回傳值只能是基本型別、Class、String、Enum,可以通過default關鍵字宣告引數的默認值 語法如下
[public|final] @interface 注解名
{
注解元素
}
注意:(1)不可與i繼承其他注解或者介面;(2)@interface只能用來宣告一個注解;(3)注解元素是一個無引數方法,方法的型別表示注解的型別 注解元素的語法語法如下:
資料型別 注解元素名() [default 默認值];
如果只有一個注解元素,在注解元素名為value的情況下,在使用的時候就可以不寫出注解元素名,只需要給出注解值即可, 使用位置:前一行或者同一行,并且在自定義注解后面的括號中寫出注解的值,(不寫則是默認值)
1.注解元素的值
注解元素一定要有確切的值,可以在定義的時候指定他的默認值,也可以在使用注解的時候指定默認值,非基本型別的注解元素的值不能為null,因此經常使用空字串或者0作為默認值,
package com.bjpowernode.java_learning;
import java.lang.annotation.Retention;
import java.lang.reflect.Field;
@Retention(RetentionPolicy.RUNTIME)//元注解,運行時保留注解,必須有,否則注解值讀不出來
@interface ApplianceMaker //定義注解
{
//定義注解元素,都有默認值
public String type() default "電視機";
public String id() default "001";
public String maker() default "TCL有限公司";
public String address() default "廣東省惠州市";
}
@Retention(RetentionPolicy.RUNTIME)
@interface ApplianceSaler {
public String name() default "京東";
public String id() default "001";
public String address() default "北京";
}
@Retention(RetentionPolicy.RUNTIME)
@interface AppliancePrice{
//注解元素只有一個,名為value
public int value() default 1200;
}
class Appliance{
//為域maker加注解,給部分元素賦值,其余使用默認值
//如果注解元素都用默認值,則直接寫@ApplianceMaker
@ApplianceMaker(type="電腦",id="201")
public String maker;
@ApplianceSaler(name="蘇寧",id="222",address="南京")
public String saler; //域有注解
@AppliancePrice(999) //也可以寫成"value=https://www.cnblogs.com/ruigege0000/p/999",因為只有一個,此處只寫出值即可
public int price; //域有注解
public void setMaker(String m) {
maker = m;
}
public String getMaker() {
return maker;
}
public void setSaler(String saler) {
this.saler = saler;
}
public String getSaler() {
return saler;
}
public void setPrice(int price) {
this.price = price;
}
public int getPrice() {
return price;
}
}
public class D144_1_Test {
public static void main(String[] args) {
System.out.println(readAnnotation(Appliance.class));
}
//讀取注解資訊
private static String readAnnotation(Class aClass) {
String maker="制造商:";
String saler="銷售商:";
String price="價格:";
Field fields[] = aClass.getDeclaredFields(); //獲取Appliance類的所有欄位
for(Field aField:fields) {
//對每一個欄位判斷其注解型別
if(aField.isAnnotationPresent(ApplianceMaker.class)) {
ApplianceMaker aMaker; //宣告一個注釋變數
//呼叫getAnnotation()方法獲得在aField域上的注解“實體”
aMaker = (ApplianceMaker)aField.getAnnotation(ApplianceMaker.class);
maker+=aMaker.type() + " "; //獲取type元素的值
maker+=aMaker.id() + " ";
maker+=aMaker.maker() + " ";
maker+=aMaker.address() + "\n";
}else if(aField.isAnnotationPresent(ApplianceSaler.class)) {
//欄位的注解是ApplianceSaler型別
ApplianceSaler aSaler;
aSaler=(ApplianceSaler)aField.getAnnotation(ApplianceSaler.class);
saler+=aSaler.name()+" ";
saler+=aSaler.id() +" ";
saler+=aSaler.address() + "\n";
}else if(aField.isAnnotationPresent(AppliancePrice.class)) {
AppliancePrice thePrice;
thePrice = (AppliancePrice)aField.getAnnotation(AppliancePrice.class);
price+=thePrice.value();
}
}
return maker+saler+price;
}
}
二、反射
定義:程式可以訪問、檢測和修改它本身狀態或者行為的一種能力 作用:使程式代碼能夠得到裝載到Java虛擬機中的類的內部資訊 Java語言的反射機制:對于任何一個物件,都能夠知道這個物件所在的類的所有方法和屬性,都能夠呼叫它的任意一個方法和訪問屬性 反射機制的功能:(1)運行時判斷任意一個物件所屬的類;(2)運行時構造人一個類的物件;(3)運行時判斷人一個類所具有的成員變數和方法;(4)生成動態代理,
1.反射類的內容
包括 java.lang.Class類和java.lang.reflect包中的Field類、Constructor類、Method類和Array類接下來一一介紹
2.Class類
該類的實體表示正在運行的Java應用程式中的類和介面,它是Java反射的基礎,對于任何一個類,首先要產生一個Class物件,然后才可以通過Class類獲得其他資訊,
3.Field類
該類提供有關類和介面的單個欄位的資訊以及對它的動態訪問權限,反射的欄位可能是一個類(靜態)欄位或者實體欄位,該類封裝了反射類的屬性,
4.Method類
該類提供了關于類和介面上單獨某個方法的資訊,該方法可能時類方法或者實體方法(包括抽象方法),該類是用來封裝反射類的方法,
5.Constructor類
該類提供了關于類的單個構造方法的資訊以及對它的訪問權限,該類封裝了反射類的構造方法
6.Array類
該類提供了動態創建和訪問Java陣列的方法,它提供的方法都是靜態方法,
三、講解Class類
獲取Class物件的三種方式
Object obj = new Object();
Class c1 = obj.getClass();//通過Object類中的getClass()方法來獲取Class物件
class c2 = Class.forName("java.lang.Integer");
//通過Class類的靜態方法forName()來獲取Class類的物件
//方法中的引數必選是類或者介面的全名,注意要捕捉ClassNotFoundException
Class c3 = Integer.class;//通過類名直接獲取
Class類的常用方法
| 型別 | 方法 | 說明 |
|---|---|---|
| Class | forName(String className) | 回傳指定字串名的類或者介面的Class類物件 |
| String | getName() | 回傳此Class物件所表示的物體的全限定名 |
| Constructor | getConstructor(Class.. parameterTypes) | 回傳此Class物件所表示的物體的指定public構造方法 |
| Constructor[] | getConstructor() | 回傳所有的public構造方法 |
| Constructor | getDeclaredConstructor(Class.parameterTypes) | 回傳Class類物件所表示的物體的指定構造方法 |
| Constructor[] | getDeclaredConstructors() | 回傳所有的構造方法 |
| Annotation[] | getDeclardAnnotations() | 回傳此元素上的所有的注解 |
| Field | getField() | 回傳此Class物件所表示的類或者介面指定的public欄位 |
| Field[] | getFields() | ...............物體的所有的public欄位 |
| Field[] | getDeclaredFields(String name) | .......物體的所有欄位 |
| Class[] | getInterface() | .......類或者介面實作的所有介面Class串列 |
| Method | getMethod(String name,Class...paramterTypes) | 回傳指定的方法,name時指定的方法的名稱,parametersTypes是指定方法的引數資料型別 |
package com.bjpowernode.java_learning;
import java.lang.reflect.*;
public class D144_4_ClassTest {
public static void main(String[] args) {
try {
//獲取指定類的Class物件
Class c = Class.forName("java.util.Date");
//獲取類的包資訊
Package p = c.getPackage();
//包名
String pname = p.getName();
System.out.println("Date類包資訊:"+p);
System.out.println("Date類包名"+pname);
//獲取類的修飾符
int m = c.getModifiers();
String str = Modifier.toString(m);
System.out.println("Date的修飾符:"+str);
System.out.println("Date類名:"+c.getName());
//獲取Date類的欄位
Field[] f = c.getDeclaredFields();
System.out.println("---回圈輸出Date類中的欄位名---");
for(Field field:f) {
System.out.print(field.getName() + " ");
}
System.out.println();
//獲取類的構造方法
Constructor[] con = c.getDeclaredConstructors();
System.out.println("--回圈輸出Date類中的構造方法資訊---");
for(Constructor cc:con) {
System.out.println(cc.getName() + "的修飾符:"+Modifier.toString(cc.getModifiers()));
Parameter[] ps = cc.getParameters();
System.out.println(cc.getName() + "的引數:");
for(Parameter pp :ps) {
System.out.print(pp.getName() + " ");
}
System.out.println();
}
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
}
}

四、原始碼:
D144_1_Test.java D143_2_SubClass.java D143_3_Test.java D144_4_ClassTest.java https://github.com/ruigege66/Java/blob/master/D144_1_Test.javahttps://github.com/ruigege66/Java/blob/master/D143_2_SubClass.javahttps://github.com/ruigege66/Java/blob/master/D143_3_Test.javahttps://github.com/ruigege66/Java/blob/master/D144_4_ClassTest.javahttps://github.com/ruigege66/Java/tree/master/ibank CSDN:https://blog.csdn.net/weixin_44630050 博客園:https://www.cnblogs.com/ruigege0000/ 歡迎關注微信公眾號:傅里葉變換,個人賬號,僅用于技術交流 
1000.0
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/168436.html
標籤:Java
上一篇:第 7 章 本地方法堆疊詳解
