日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[java学习笔记]-注解和反射

發布時間:2023/12/16 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [java学习笔记]-注解和反射 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

[java學習筆記]-注解和反射

  • 注解
  • 元注解
  • 自定義注解
  • 反射
  • 獲取其他的類
  • 類型的Class對象
  • 類加載內存分析
  • 分析類的初始化
  • 類加載器的作用
  • 創建運行時類的對象
  • 動態創建對象執行的方法
  • 性能對比分析
  • 獲取泛型信息
  • 獲取注解信息


注解

@Override 規則和約束@Deprecated 危險的方法,過時的方法@SuppressWarnings 抑制編譯時的警告信息

@Override

public class Test1 {//@Override是重寫的注解@Overridepublic String toString() {return super.toString();} }

@Deprecated

//Deprecated不推孝程序員使用,但是可以使用。或者存在更好的方式 @Deprecated public static void test(){System.out.println("Deprecated"); }

@SuppressWarnings

@SuppressWarnings("all") public void test1(){List list = new ArrayList(); }

元注解

@Documented @Target() @Retention() @Inherited

定義一個注解

//定義一個注解 public @interface MyAnnotation{ }

把注解的范圍限制在方法和類中

//類注解 @MyAnnotation public class Test2 {//方法注解@MyAnnotationpublic void test(){} }//定義一個注解 @Target(value = {ElementType.METHOD,ElementType.TYPE}) @interface MyAnnotation{ } //Retention表示我們的注解在什么地方還有效。 //runtime>class>source @Retention(value = RetentionPolicy.RUNTIME) @interface MyAnnotation{ }//Documented表示是否將我們的注解生成在JAVAdoc中 @Documented//子類可以繼承父類的注解 @Inherited

自定義注解

關鍵字 @interface

多參數

public class Test2 {//注解可以顯示賦值,如果沒有默認值,我們就必須給注解賦值@MyAnnotation(name = "Muz1")public void test(){} }@Target({ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation{//注解的參數: 參數類型 + 參數名();String name() default "";int age() default 0;int id() default -1;//如果默認值為-1,代表不存在,indexof,如果找不到就返回-1String[] schools() default {"牛馬大學","說唱帶專"} }

單參數

public class Test2 {//注解可以顯示賦值,如果沒有默認值,我們就必須給注解賦值@MyAnnotation("Muz1")public void test(){} }@Target({ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation{String[] value(); }

參數名是 value() 可以省略注解參數


反射

Reflection (反射)是Java被視為動態語言的關鍵,反射機制允許程序在執行期借助于Reflection API取得任何類的內部信息,并能直接操作任意對象的內部屬性及方法

Class c = Class.forName("java.lang.String");

加載完類之后,在堆內存的方法區中就產生了已個Class類型的對象(一個類只有一個Class對象) ,這個對象就包含了完整的類的結構信息。我們可以通過這個對象看到類的結構。這個對象就像一面鏡子, 透過這個鏡子看到類的結構,所以,我們形象的稱之為:反射

獲取一個簡單反射

//Test.java//反射 public class Test {public static void main(String[] args) throws ClassNotFoundException {//通過反射獲取類的Class對象Class c1 = Class.forName("com.Reflection.User");System.out.println(c1);} } //實體類 pojo entity class User{private String name;private int id;private int age;public User(String name, int id, int age) {this.name = name;this.id = id;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getId() {return id;}public void setId(int id) {this.id = id;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", id=" + id +", age=" + age +'}';} }

可以看到這個類有很多方法


獲取其他的類

//Test.java public class Test {public static void main(String[] args) throws ClassNotFoundException {//通過反射獲取類的Class對象Class c1 = Class.forName("com.Reflection.User");System.out.println(c1);Class c2 = Class.forName("com.Reflection.User");Class c3 = Class.forName("com.Reflection.User");Class c4 = Class.forName("com.Reflection.User");System.out.println(c2.hashCode());System.out.println(c3.hashCode());System.out.println(c4.hashCode());} }......

一個類在內存中只有一個Class
一個類被加載后,類的整個結構都會被封裝在Class對象中。

測試class類的創建方式有哪些

package com.Reflection; //測試Class類的創建方式有哪些 public class Test1 {public static void main(String[] args) throws ClassNotFoundException {Person person = new Student();System.out.println("這個人是:"+person.name);//方式一: 通過對象獲得Class c1 = person.getClass();System.out.println(c1.hashCode());//方式二: forName獲得Class c2 = Class.forName("com.Reflection.Student");System.out.println(c2.hashCode());//方式三: 通過類名.class獲得Class c3 = Student.class;System.out.println(c3.hashCode());//方式四: 基本內置類型的包裝類都有一個Type屬性Class c4 = Integer.TYPE;System.out.println(c4);//獲得父類類型Class c5 = c1.getSuperclass();System.out.println(c5);} }class Person{public String name;public Person() {this.name = name;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +'}';} } class Student extends Person{public Student() {this.name="學生";} } class Teacher extends Person{public Teacher() {this.name="老師";} }


類型的Class對象

//Test2.javapackage com.Reflection; import java.lang.annotation.ElementType;//所有類型的Class public class Test2 {public static void main(String[] args) {Class c1 = Object.class; //類Class c2 = Comparable.class; //接口Class c3 = String[].class; //一維數組Class c4 = int[][].class; //二維數組Class c5 = Override.class; //注解Class c6 = ElementType.class; //枚舉Class c7 = Integer.class; //基本數據類型Class c8 = void.class; //voidClass c9 = Class.class; //ClassSystem.out.println("類: " + c1);System.out.println("接口: " + c2);System.out.println("一維數組: " + c3);System.out.println("二維數組: " + c4);System.out.println("注解: " + c5);System.out.println("枚舉: " + c6);System.out.println("基本數據類型: " + c7);System.out.println("void: " + c8);System.out.println("Class: " + c9);} }


類加載內存分析

小測試

//Test3.java package com.Reflection; public class Test3 {public static void main(String[] args) {A a = new A();System.out.println(A.m);} } class A{static {System.out.println("A類靜態代碼塊初始化");m = 300;}static int m = 100;public A() {System.out.println("A類的無參構造器初始化");} }

1.加載到內存,會產生一個類對應的class對象 2.鏈接,鏈接結束后 m = 0 3.初始化<clinit>(){System.out.println("A類靜態代碼塊初始化");m = 300;m = 100;}m = 100;

分析類的初始化


Demo

Test4.javapackage com.Reflection; //測試類什么時候會初始化 public class Test4 {static {System.out.println("main類被加載");}public static void main(String[] args) {} } class Father{static int b = 2;static {System.out.println("父類被加載");} } class Son extends Father{static {System.out.println("子類被加載");m = 300;}static int m = 100;static final int M = 1; }

然后在main方法中加入

public static void main(String[] args) {//1.主動引用Son son = new Son(); }

輸出

反射

public static void main(String[] args) throws ClassNotFoundException {//反射也會產生主動引用Class.forName("com.Reflection.Son"); }

輸出

不會產生類的引用方法

public static void main(String[] args) {//不會產生類的引用方法System.out.println(Son.b); }

數組

public static void main(String[] args) {Son[] array = new Son[5]; }

常量

public static void main(String[] args) {System.out.println(Son.M); }


類加載器的作用

類加載器

package com.Reflection; public class Test5 {public static void main(String[] args) throws ClassNotFoundException {//獲取系統類的加載器ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();System.out.println(systemClassLoader);//獲取系統類加載器的父類加載器-->拓展類加載器ClassLoader parent = systemClassLoader.getParent();System.out.println(parent);//獲取系統類加載器的父類加載器-->根加載器(C/C++)ClassLoader parent1 = parent.getParent();System.out.println(parent1);//測試當前類是哪個加載器ClassLoader c1 = Class.forName("com.Reflection.Test5").getClassLoader();System.out.println(c1);//測試JDK內置的類是誰加載的ClassLoader c2 = Class.forName("java.lang.Object").getClassLoader();System.out.println(c2);//如何獲得系統加載器可以加載的路徑System.out.println(System.getProperty("java.class.path"));} }


創建運行時類的對象

之前的 User類

//Test6.java //獲得類的信息 public class Test6 {public static void main(String[] args) throws ClassNotFoundException {Class c1 = Class.forName("com.Reflection.User");//獲得類的名字System.out.println(c1.getName());System.out.println(c1.getSimpleName());} }

獲得類的屬性

//Test6.java public class Test6 {public static void main(String[] args) throws ClassNotFoundException {Class c1 = Class.forName("com.Reflection.User");//獲得類的屬性Field[] fields = c1.getFields(); //只能找到public屬性fields = c1.getDeclaredFields(); //能找到所有的屬性for (Field field : fields) {System.out.println(field);}//獲得指定屬性的值Field name = c1.getDeclaredField("name");System.out.println(name);} }

//Test6.java public class Test6 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {Class c1 = Class.forName("com.Reflection.User");//獲得類的方法//獲得本類及其父類的全部public方法Method[] methods = c1.getMethods();for (Method method : methods) {System.out.println("正常的: " + method);}//獲得本類的所有方法methods = c1.getDeclaredMethods();for (Method method : methods) {System.out.println("getDeclaredMethods: " + method);}} }

獲得指定的方法

//Test6.java public class Test6 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {Class c1 = Class.forName("com.Reflection.User");//獲得指定的方法Method getNames = c1.getMethod("getName", null);Method setNames = c1.getMethod("setName", String.class);System.out.println(getNames);System.out.println(setNames);} }


動態創建對象執行的方法

通過反射動態的創建對象

//Test7.java//通過反射動態的創建對象 public class Test7 {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {//獲得Class對象Class c1 = Class.forName("com.Reflection.User");//構造一個對象User user = (User)c1.newInstance(); //本質上調用了類的無參構造器System.out.println(user);} }

把User類的無參構造器刪除

再次運行報錯

使用newInstance()函數創建函數,必須有無參構造器

通過構造器創建對象

//Test7.java //通過構造器創建對象 Constructor c2 = c1.getDeclaredConstructor(String.class, int.class, int.class); Object muz1 = c2.newInstance("Muz1", 1, 0); System.out.println(muz1);

通過反射調用普通方法

//通過反射調用普通方法 User user = (User)c1.newInstance(); //通過反射獲取一個方法 Method setName = c1.getDeclaredMethod("setName", String.class); setName.invoke(user,"Muz1"); System.out.println(user.getName());

通過反射操作屬性

//通過反射操作屬性 User user1 = (User)c1.newInstance(); Field name = c1.getDeclaredField("name"); name.set(user1,"Muz12"); System.out.println(user1.getName());

輸出報錯,因為 User類里面都是 private 方法

添加一行代碼

//name.setAccessible(true);User user1 = (User)c1.newInstance(); Field name = c1.getDeclaredField("name");//不能直接操作私有屬性,需要關閉程序安全檢測 name.setAccessible(true);name.set(user1,"Muz12"); System.out.println(user1.getName());

成功輸出


性能對比分析

Demo

三種方式的性能表現

package com.Reflection; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; //分析性能問題 public class Test8 {//普通方式public static void test1(){User user = new User();long startTime = System.currentTimeMillis();for(int i = 0; i < 1000000000; i++){user.getName();}long endTime = System.currentTimeMillis();System.out.println("普通方式執行10億次"+(endTime-startTime)+"ms");}//反射方式public static void test2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {User user = new User();Class c1 = user.getClass();Method getName = c1.getDeclaredMethod("getName", null);long startTime = System.currentTimeMillis();for(int i = 0; i < 1000000000; i++){getName.invoke(user,null);}long endTime = System.currentTimeMillis();System.out.println("反射方式執行10億次"+(endTime-startTime)+"ms");}//反射方式,關閉檢測public static void test3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {User user = new User();Class c1 = user.getClass();Method getName = c1.getDeclaredMethod("getName", null);getName.setAccessible(true);long startTime = System.currentTimeMillis();for(int i = 0; i < 1000000000; i++){getName.invoke(user,null);}long endTime = System.currentTimeMillis();System.out.println("反射方式,關閉檢測執行10億次"+(endTime-startTime)+"ms");}public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {test1();test2();test3();} }


獲取泛型信息

Demo

//Test9.java package com.Reflection; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map;//通過反射獲取泛型 public class Test9 {public void test1(Map<String,User> map, List<User> list){System.out.println("test1");}public Map<String,User> test2(){System.out.println("test2");return null;}public static void main(String[] args) throws NoSuchMethodException {Method method = Test9.class.getMethod("test1", Map.class, List.class);Type[] genericParameterTypes = method.getGenericParameterTypes();for (Type genericParameterType : genericParameterTypes) {System.out.println("#"+genericParameterType);if(genericParameterType instanceof ParameterizedType){Type[] actualTypeArguments = ((ParameterizedType)genericParameterType).getActualTypeArguments();for (Type actualTypeArgument : actualTypeArguments) {System.out.println(actualTypeArgument);}}}System.out.println("========================================");method = Test9.class.getMethod("test2",null);Type genericReturnType = method.getGenericReturnType();if(genericReturnType instanceof ParameterizedType){Type[] actualTypeArguments = ((ParameterizedType)genericReturnType).getActualTypeArguments();for (Type actualTypeArgument : actualTypeArguments) {System.out.println(actualTypeArgument);}}} }


獲取注解信息

Demo

//Test10.javapackage com.Reflection; import java.lang.annotation.*; //聯系反射操作注解 public class Test10 {public static void main(String[] args) throws ClassNotFoundException {Class c1 = Class.forName("com.Reflection.Student2");//通過反射獲得注解Annotation[] annotations = c1.getAnnotations();for (Annotation annotation : annotations) {System.out.println(annotation);}} }@AbbMuz1("db_Student") class Student2{@BbbMuz1(columnName = "db_id",type = "int" ,length = 10)private int id;@BbbMuz1(columnName = "db_age",type = "int" ,length = 10)private int age;@BbbMuz1(columnName = "db_name",type = "varchar" ,length = 10)private String name;public Student2() {}public Student2(int id, int age, String name) {this.id = id;this.age = age;this.name = name;}public int getId() {return id;}public void setId(int id) {this.id = id;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Student2{" +"id=" + id +", age=" + age +", name='" + name + '\'' +'}';} }//類名注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface AbbMuz1{String value(); } //屬性的注解 @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface BbbMuz1{String columnName();String type();int length(); }

獲得注解輸出

獲得注解value的值

在main方法中添加

//獲得注解value的值 AbbMuz1 annotation = (AbbMuz1)c1.getAnnotation(AbbMuz1.class); String value = annotation.value(); System.out.println(value);

獲得類指定的注解

在main方法中添加

//獲得類指定的注解 Field f = c1.getDeclaredField("name"); BbbMuz1 annotation1 = f.getAnnotation(BbbMuz1.class); System.out.println(annotation1.columnName()); System.out.println(annotation1.type()); System.out.println(annotation1.length());

總結

以上是生活随笔為你收集整理的[java学习笔记]-注解和反射的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。