新聞中心
- 注解
- 什么是注解
- 常用注解
- 自定義注解
- 格式:
- 例子
- 定義
- 使用
- 元注解
- @Retention
- 反射
- 反射的概述
- Java反射機(jī)制(自審機(jī)制)
- 一般調(diào)用方法和反射調(diào)用方法比較
- 反射獲取構(gòu)造方法并使用
- 獲取Class類的對(duì)象
- Class類中用于獲取構(gòu)造方法的方法
- Constructor類中用于創(chuàng)建對(duì)象的方法
- 練習(xí)
- 小結(jié)
- 反射獲取成員變量
- 步驟
- 反射獲取成員方法并運(yùn)行
- 步驟
- 練習(xí)
- 綜合應(yīng)用(注解+反射)
- 自定義注解類
- 要運(yùn)行的類
- main方法運(yùn)行看效果
- 運(yùn)行效果
注解的主要作用:對(duì)我們的程序進(jìn)行標(biāo)注和解釋。
(可以理解成:注釋是寫給人看的;注解是寫給jvm看的)
如:
public @interface 注解名稱 {public 屬性類型 屬性名() default 默認(rèn)值 ;//屬性類型可以是:基本數(shù)據(jù)類型,String,Class,注解,枚舉,以上類型的一維數(shù)組
}
例子
定義@Retention(RetentionPolicy.CLASS)//元注解,運(yùn)行時(shí)注解的作用時(shí)間范圍。
@Target(ElementType.METHOD)//元注解,類可以在什么上面使用。
public @interface MyTest {String name();
int code() default 200;
}
使用public class Main {@MyTest(name = "0",code = 200)//有默認(rèn)值就可以不寫,當(dāng)你要寫code = 200時(shí)可以寫成@MyTest(name = "0")
public void annotationTest(){}
}
元注解元注解:就是描述注解的注解。
- @Retention(RetentionPolicy.CLASS)//注釋將被編譯器記錄在類文件中,但不需要在運(yùn)行時(shí)由虛擬機(jī)保留。
- @Retention(RetentionPolicy.RUNTIME)//注釋要記錄在類文件由編譯器和運(yùn)行時(shí)虛擬機(jī)保留的,所以他們可以讀沉思。
- @Retention(RetentionPolicy.SOURCE)//注釋將被編譯器丟棄。
注解一般用在寫一個(gè)通用的程序框架的場合。它通常和反射結(jié)合起來使用;
是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;
對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意屬性和方法;
這種動(dòng)態(tài)獲取信息以及動(dòng)態(tài)調(diào)用對(duì)象方法的功能稱為Java語言的反射機(jī)制。
利用反射可以無視修飾符獲取類里面所有的屬性和方法。
先獲取配置文件中的信息,動(dòng)態(tài)獲取信息并創(chuàng)建對(duì)象和調(diào)用方法
一般調(diào)用方法和反射調(diào)用方法比較一般:1. 創(chuàng)建這個(gè)類的對(duì)象 2. 用對(duì)象調(diào)用方法;
反射:1. 利用class對(duì)象來創(chuàng)建的 2. 反射方式:創(chuàng)建對(duì)象 3. 反射方式:調(diào)用方法
對(duì)象:
- Class.forName(“全類名”);
- 類名.class
- 對(duì)象.getClass();
Constructor>[] getConstructors?():返回所有公共構(gòu)造方法對(duì)象的數(shù)組 Constructor>[] getDeclaredConstructors?():返回所有構(gòu)造方法對(duì)象的數(shù)組
Constructor getConstructor?(Class>... parameterTypes):返回單個(gè)公共構(gòu)造方法對(duì)象 Constructor getDeclaredConstructor?(Class>… parameterTypes):返回單個(gè)構(gòu)造方法對(duì)象
T newInstance?(Object… initargs):根據(jù)指定的構(gòu)造方法創(chuàng)建對(duì)象
setAccessible(boolean flag):設(shè)置為true,表示取消訪問檢查
person實(shí)體類(后面將用這個(gè)類來演示):
public class Person implements Serializable {private String name;
private int age;
private String address;
public Person() {}
public Person(String name) {this.name = name;
}
private Person(String name, int age, String address) {this.name = name;
this.age = age;
this.address = address;
}
@Override
public String toString() {return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
private void study(){System.out.println("私有方法執(zhí)行了-----");
}
}
public class Main {public static void main(String[] args) {try {// 獲取到Person類的class對(duì)象。
Class>aClass = Class.forName("com.jifu.test.bean.Person");
//創(chuàng)建Person對(duì)象
Person person = (Person) aClass.newInstance();
//獲得com.jifu.test.bean.Person這個(gè)對(duì)象的所有構(gòu)造方法,包括私有的。
Constructor[] allConstructors = aClass.getDeclaredConstructors();
//獲得com.jifu.test.bean.Person這個(gè)對(duì)象的public修飾的構(gòu)造方法。
Constructor[] constructors = aClass.getConstructors();
//獲得參數(shù)類型為(String.class,int.class,String.class)的構(gòu)造方法,包括私有的。
Constructor>constructor = aClass.getDeclaredConstructor(String.class,int.class,String.class);
//設(shè)置為true 表示取消訪問檢查。
constructor.setAccessible(true);
Person person = (Person)constructor.newInstance("小明", 18, "北京");
}catch (ClassNotFoundException | InstantiationException | IllegalAccessException |NoSuchMethodException e) {e.printStackTrace();
}
}
}
小結(jié)獲取class對(duì)象
三種方式 ---- Class.forName(“全類名”)
獲取里面的構(gòu)造方法對(duì)象
getConstructor (Class>... parameterTypes) getDeclaredConstructor (Class>… parameterTypes)
如果是public的,直接創(chuàng)建對(duì)象
newInstance(Object… initargs)
如果是非public的,需要臨時(shí)取消檢查,然后再創(chuàng)建對(duì)象
setAccessible(boolean)(暴力獲?。?/p>反射獲取成員變量
步驟
第一步:獲得class對(duì)象
Class.forName(“全類名”);
第二步:獲得Field對(duì)象
Field[] getFields():返回所有公共成員變量對(duì)象的數(shù)組
Field[] getDeclaredFields():返回所有成員變量對(duì)象的數(shù)組
Field getField(String name):返回單個(gè)公共成員變量對(duì)象
Field getDeclaredField(String name):返回單個(gè)成員變量對(duì)象
第三步:賦值或者獲取值
void set(Object obj, Object value):賦值
Object get(Object obj)獲取值。
第一步:獲得class對(duì)象
Class.forName(“全類名”);
第二步:獲得Method對(duì)象
Method ] getMethods():返回所有公共成員方法對(duì)象的數(shù)組,包括繼承的
Method[] getDeclaredMethods():返回所有成員方法對(duì)象的數(shù)組,不包括繼承的
Method getMethod(String name, Class>... parameterTypes):返回單個(gè)公共成員方法對(duì)象 Method getDeclaredMethod(String name, Class>… parameterTypes):返回單個(gè)成員方法對(duì)象
public class Main {public static void main(String[] args) {try {// 獲取到Person類的class對(duì)象。
Class>aClass = Class.forName("com.jifu.test.bean.Person");
//獲得參數(shù)類型為(String.class,int.class,String.class)的構(gòu)造方法,包括私有的。
Constructor>constructor = aClass.getDeclaredConstructor(String.class,int.class,String.class);
//設(shè)置為true 表示取消訪問檢查。
constructor.setAccessible(true);
//創(chuàng)建Person對(duì)象
Person person = (Person)constructor.newInstance("小明", 18, "北京");
//獲得名為study的Person對(duì)象中的方法對(duì)象(第一個(gè)參數(shù)是方法名,后面的參數(shù)是方法參數(shù)的類型)
Method study = aClass.getDeclaredMethod("study", null);
//設(shè)置為true 表示取消訪問檢查。
study.setAccessible(true);
//執(zhí)行方法(第一個(gè)參數(shù)是調(diào)用該方法的對(duì)象,后面的參數(shù)是方法中要傳的參數(shù)值)
study.invoke(person,null);
}catch (ClassNotFoundException | InstantiationException | IllegalAccessException |NoSuchMethodException e) {e.printStackTrace();
}
}
}
綜合應(yīng)用(注解+反射)需求:一個(gè)類里面只要是標(biāo)注了 @MyTest注解的就自動(dòng)運(yùn)行
自定義注解類package com.jifu.test.enumTest;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME) //此處必須是RUNTIME才能看到效果
@Target(ElementType.METHOD)
public @interface MyTest {String name();
int code() default 200;
}
要運(yùn)行的類package com.jifu.test.enumTest;
public class TestDame {@MyTest(name = "知識(shí)")
public void TestMethod(){System.out.println("測試方法1");
}
@Deprecated
@MyTest(name = "知識(shí)",code = 201)
private void TestMethod2(){System.out.println("測試方法2");
}
public void TestMethod3(){System.out.println("測試方法3");
}
}
main方法運(yùn)行看效果package com.jifu.test.enumTest;
import com.jifu.test.bean.Person;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Main {public static void main(String ... args){ try { //獲取到"com.jifu.test.enumTest.TestDame"類的class對(duì)象。
Class>aClass = Class.forName("com.jifu.test.enumTest.TestDame");
// 獲得TestDame的無參構(gòu)造。
Constructor>declaredConstructor = aClass.getDeclaredConstructor(null);
//通過無參構(gòu)造方法獲得TestDame實(shí)例對(duì)象。
TestDame testDame = (TestDame)declaredConstructor.newInstance();
//獲得"com.jifu.test.enumTest.TestDame"類的所有方法包括非public的
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {//打印每個(gè)方法
System.out.println(declaredMethod);
//獲得這個(gè)方法中的所有注解
final Annotation[] declaredAnnotations = declaredMethod.getDeclaredAnnotations();
for (Annotation declaredAnnotation : declaredAnnotations) { //遍歷打印每個(gè)注解
System.out.println(declaredAnnotation);
//判斷注解是不是MyTest.class類型
if (declaredAnnotation.annotationType()==MyTest.class){ //設(shè)置取消方法受檢。
declaredMethod.setAccessible(true);
//如果注解是MyTest.class類型就運(yùn)行,需要傳入對(duì)象的類型
declaredMethod.invoke(testDame);
}
}
}
}
} catch (ClassNotFoundException e) {e.printStackTrace();
}
}
}
運(yùn)行效果Z:\jdk-11.0.1\bin\java.exe "-javaagent:D:\idea\IntelliJ IDEA 2021.1\lib\idea_rt.jar=63709:D:\idea\IntelliJ IDEA 2021.1\bin" -Dfile.encoding=UTF-8 -classpath F:\zhifei\zhifei\test\target\classes com.jifu.test.enumTest.Main
public void com.jifu.test.enumTest.TestDame.TestMethod() //TestMethod()方法上只有一個(gè)@MyTest注解
@com.jifu.test.enumTest.MyTest(code=200, name="知識(shí)")
測試方法1 //方法運(yùn)行了
private void com.jifu.test.enumTest.TestDame.TestMethod2() //TestMethod2()方法上有一個(gè)@MyTest注解 和 @Deprecated注解
@java.lang.Deprecated(forRemoval=false, since="")
@com.jifu.test.enumTest.MyTest(code=201, name="知識(shí)")
測試方法2 //方法運(yùn)行了
public void com.jifu.test.enumTest.TestDame.TestMethod3() //TestMethod3()方法上沒有t注解
Process finished with exit code 0
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
網(wǎng)頁標(biāo)題:java——注解,反射-創(chuàng)新互聯(lián)
網(wǎng)頁網(wǎng)址:http://www.dlmjj.cn/article/dcdoes.html