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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

闭关修炼(八)反射机制

發布時間:2023/12/14 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 闭关修炼(八)反射机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 反射
    • 什么是反射機制?
    • 反射機制的作用
    • 通過java反射機制創建對象例子
      • 使用默認無參構造函數創建對象
      • 使用有參構造函數創建對象
    • 怎么禁止反射機制?
    • spring中的運用場景
    • jdbc中的運用場景
    • 使用反射機制訪問方法和屬性
      • 訪問屬性
      • 訪問方法
      • 給私有屬性賦值
  • 乞丐版springIOC實現
    • 什么是springIOC?
    • springioc過程
    • springioc創建對象
    • 實現思路
    • 實現


反射

什么是反射機制?

反射機制就是正在運行(的程序中)動態獲取類的所有信息。

反射機制的作用

  • 反編譯:.class -> .java。

  • 通過反射機制訪問對象屬性,方法,構造方法等。

  • 使用java反射機制可以不用new來初始化類。

  • 類私有屬性可以通過java反射機制賦值。

  • 提高程序的擴展性,封裝一些工具類,寫框架都會用到反射機制。

    通過java反射機制創建對象例子

    初始化類使用new創建對象,現在用反射機制來創建對象。

    使用默認無參構造函數創建對象

    package ch8;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.SneakyThrows;@Data @AllArgsConstructor @NoArgsConstructor class User{private String username;private String password; } public class Test1 {@SneakyThrowspublic static void main(String[] args) {// forName中寫類的完整路徑,即包名+類名Class<?> aClass = Class.forName("ch8.User");// 使用默認無參構造函數創建對象User user = (User) aClass.newInstance();System.out.println(user);} }

    使用有參構造函數創建對象

    package ch8;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import lombok.SneakyThrows;import java.lang.reflect.Constructor;@Data @AllArgsConstructor @NoArgsConstructor class User{private String username;private String password; } public class Test1 {@SneakyThrowspublic static void main(String[] args) {/*// forName中寫類的完整路徑,即包名+類名Class<?> aClass = Class.forName("ch8.User");// 使用默認無參構造函數創建對象User user = (User) aClass.newInstance();System.out.println(user);*/// forName中寫類的完整路徑,即包名+類名Class<?> aClass = Class.forName("ch8.User");// 使用getConstructor獲取有參構造函數// 參數傳入有參構造函數的參數類型Constructor<?> constructor = aClass.getConstructor(String.class, String.class);// 創建對象User user2 = (User) constructor.newInstance("jack", "123");System.out.println(user2);} }

    怎么禁止反射機制?

    把構造函數改成private修飾,但是反射還是能通過設置訪問權限禁止禁止反射

    spring中的運用場景

    寫標簽的時候經常遇到類似下面的格式
    <bean id=“user” class=“com.java.bean.User”>
    class值寫類的reference path,目的之一就是通過反射機制實例化對象

    springIoc

    jdbc中的運用場景

    在加載jdbc驅動類的時候我們會寫:
    class.forNmae(“com.mysql.jdbc.Driver”)

    使用反射機制訪問方法和屬性

    訪問屬性

    package ch8;import java.lang.reflect.Field;public class Test2 {public static void main(String[] args) throws ClassNotFoundException {// 獲取類的字節碼文件Class<?> aClass = Class.forName("ch8.User");// 獲取當前類的所有屬性Field[] declaredFields = aClass.getDeclaredFields();// 遍歷for (Field field : declaredFields) {// 打印名稱System.out.println(field.getName());}} }

    訪問方法

    package ch8;import java.lang.reflect.Field; import java.lang.reflect.Method;public class Test2 {public static void main(String[] args) throws ClassNotFoundException {// 獲取類的字節碼文件Class<?> aClass = Class.forName("ch8.User");// 獲取類的所有方法Method[] declaredMethods = aClass.getDeclaredMethods();// 遍歷輸出for (Method m : declaredMethods){System.out.println(m.getName());}} }

    給私有屬性賦值

    package ch8;import java.lang.reflect.Field; import java.lang.reflect.Method;public class Test2 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {// 獲取類的字節碼文件Class<?> aClass = Class.forName("ch8.User");// 實例化對象User user = (User) aClass.newInstance();// 獲取屬性Field username = aClass.getDeclaredField("username");// 設置權限,允許操作私有屬性username.setAccessible(true);// 屬性賦值,第一個參數是類的對象, 第二個參數是賦的值username.set(user, "likeghee");// 獲取屬性Field password = aClass.getDeclaredField("password");// 設置權限password.setAccessible(true);// 屬性賦值password.set(user, "1234");// 打印System.out.println(user);} }

    乞丐版springIOC實現

    什么是springIOC?

    控制反轉,將bean與bean之間的關系交給第三方容器進行管理,不用自己手動創建對象。

    springioc過程

    加載springxml配置文件
    傳入beanid獲取bean對象

    springioc創建對象

    使用無參構造函數

    實現思路

  • 用dom4j解析xml
  • 通過beanid查找對應的xml節點,獲取class節點屬性
  • 使用java反射機制newInstance類
  • 使用java的反射機制給類屬性賦值
  • 實現

    新建一個Context.xml放到resources文件夾下,模擬spring.xml

    <?xml version="1.0" encoding="UTF-8"?> <beans><bean id="user1" class="myspringioc.User"><property name="username" value="ghee"/><property name="password" value="123"/></bean> </beans>

    新建ClassPathXmlApplicationContext類,實現它的getBean方法

    package myspringioc;import lombok.SneakyThrows; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader;import java.lang.reflect.Field; import java.util.List;public class ClassPathXmlApplicationContext {private static String PATH;private static String ID;private static String CLASS;private static String NAME;private static String VALUE;public void init() {ID = "id";CLASS = "class";NAME = "name";VALUE = "value";}// 構造函數public ClassPathXmlApplicationContext(String path) {PATH = path;}@SneakyThrowspublic Object getBean(String id) {init();/*1. 用dom4j解析xml2. 通過beanid查找對應的xml節點,獲取class節點屬性3. 使用java反射機制newInstance類4. 使用java的反射機制給類屬性賦值*/if (id.equals("")) {return null;}SAXReader saxReader = new SAXReader();// 讀取resources下的配置文件Document read = saxReader.read(this.getClass().getClassLoader().getResource(PATH));// 遍歷二級節點,查詢beanid// 獲取根節點Element rootElement = read.getRootElement();// 獲取二級節點List<Element> elements = rootElement.elements();// 遍歷查找for (Element e : elements) {// 獲取id屬性的值String beanId = e.attributeValue(ID);// 如果和傳入的id相等,找到beanif (!beanId.equals(id)) {// 如果不相等就跳出本次循環continue;}// 找到了beanid// 獲取class屬性值,也就是包PTAHString attClassPath = e.attributeValue(CLASS);// 初始化beanClass<?> aClass = Class.forName(attClassPath);Object classObj = aClass.newInstance();// 獲取三級節點List<Element> propertyList = e.elements();for(Element property: propertyList){// 獲取name屬性的值String attNameValue = property.attributeValue(NAME);// 通過反射找到類中的屬性Field declaredField = aClass.getDeclaredField(attNameValue);// 獲取value屬性的值String attValueValue = property.attributeValue(VALUE);// 設置訪問權限declaredField.setAccessible(true);// 類屬性賦值declaredField.set(classObj, attValueValue);}return classObj;}return null;}}

    測試代碼

    package myspringioc;public class Test {public static void main(String[] args) {ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("Context.xml");User user1 = (User) classPathXmlApplicationContext.getBean("user1");System.out.println(user1);} }

    乞丐版ioc實現成功了

    使用方便,但是初始化對象效率很低。

    總結

    以上是生活随笔為你收集整理的闭关修炼(八)反射机制的全部內容,希望文章能夠幫你解決所遇到的問題。

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