華為二面:說一下Java反射機(jī)制的應(yīng)用場(chǎng)景
反射的優(yōu)勢(shì)和劣勢(shì) 反射的應(yīng)用場(chǎng)景
反射的優(yōu)勢(shì)和劣勢(shì)
優(yōu)勢(shì) 運(yùn)行期類型的判斷,動(dòng)態(tài)類加載:提高代碼靈活度
劣勢(shì) 性能瓶頸:反射相當(dāng)于一系列解釋操作,通知 JVM 要做的事情,性能比直接的java代碼要慢很多
反射的應(yīng)用場(chǎng)景
JDBC 的數(shù)據(jù)庫的連接
通過Class.forName()加載數(shù)據(jù)庫的驅(qū)動(dòng)程序 (通過反射加載,前提是引入相關(guān)了Jar包) 通過 DriverManager 類進(jìn)行數(shù)據(jù)庫的連接,連接的時(shí)候要輸入數(shù)據(jù)庫的連接地址、用戶名、密碼 通過Connection 接口接收連接
public class ConnectionJDBC {/*** @param args*///驅(qū)動(dòng)程序就是之前在classpath中配置的JDBC的驅(qū)動(dòng)程序的JAR 包中public static final String DBDRIVER = "com.mysql.jdbc.Driver";//連接地址是由各個(gè)數(shù)據(jù)庫生產(chǎn)商單獨(dú)提供的,所以需要單獨(dú)記住public static final String DBURL = "jdbc:mysql://localhost:3306/test";//連接數(shù)據(jù)庫的用戶名public static final String DBUSER = "root";//連接數(shù)據(jù)庫的密碼public static final String DBPASS = "";public static void main(String[] args) throws Exception {Connection con = null; //表示數(shù)據(jù)庫的連接對(duì)象Class.forName(DBDRIVER); //1、使用CLASS 類加載驅(qū)動(dòng)程序 ,反射機(jī)制的體現(xiàn)con = DriverManager.getConnection(DBURL,DBUSER,DBPASS); //2、連接數(shù)據(jù)庫System.out.println(con);con.close(); // 3、關(guān)閉數(shù)據(jù)庫}
Spring 框架的使用
將程序內(nèi)所有 XML 或 Properties 配置文件加載入內(nèi)存中 Java類里面解析xml或properties里面的內(nèi)容,得到對(duì)應(yīng)實(shí)體類的字節(jié)碼字符串以及相關(guān)的屬性信息 使用反射機(jī)制,根據(jù)這個(gè)字符串獲得某個(gè)類的Class實(shí)例 動(dòng)態(tài)配置實(shí)例的屬性
不用每一次都要在代碼里面去new或者做其他的事情 以后要改的話直接改配置文件,代碼維護(hù)起來就很方便了 有時(shí)為了適應(yīng)某些需求,Java類里面不一定能直接調(diào)用另外的方法,可以通過反射機(jī)制來實(shí)現(xiàn)
public class BeanFactory {private Map<String, Object> beanMap = new HashMap<String, Object>();/*** bean工廠的初始化.* @param xml xml配置文件*/public void init(String xml) {try {//讀取指定的配置文件SAXReader reader = new SAXReader();ClassLoader classLoader = Thread.currentThread().getContextClassLoader();//從class目錄下獲取指定的xml文件InputStream ins = classLoader.getResourceAsStream(xml);Document doc = reader.read(ins);Element root = doc.getRootElement();Element foo;//遍歷beanfor (Iterator i = root.elementIterator("bean"); i.hasNext();) {foo = (Element) i.next();//獲取bean的屬性id和classAttribute id = foo.attribute("id");Attribute cls = foo.attribute("class");//利用Java反射機(jī)制,通過class的名稱獲取Class對(duì)象Class bean = Class.forName(cls.getText());//獲取對(duì)應(yīng)class的信息java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean);//獲取其屬性描述java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors();//設(shè)置值的方法Method mSet = null;//創(chuàng)建一個(gè)對(duì)象Object obj = bean.newInstance();//遍歷該bean的property屬性for (Iterator ite = foo.elementIterator("property"); ite.hasNext();) {Element foo2 = (Element) ite.next();//獲取該property的name屬性Attribute name = foo2.attribute("name");String value = null;//獲取該property的子元素value的值for(Iterator ite1 = foo2.elementIterator("value"); ite1.hasNext();) {Element node = (Element) ite1.next();value = node.getText();break;}for (int k = 0; k < pd.length; k++) {if (pd[k].getName().equalsIgnoreCase(name.getText())) {mSet = pd[k].getWriteMethod();//利用Java的反射極致調(diào)用對(duì)象的某個(gè)set方法,并將值設(shè)置進(jìn)去mSet.invoke(obj, value);}}}//將對(duì)象放入beanMap中,其中key為id值,value為對(duì)象beanMap.put(id.getText(), obj);}} catch (Exception e) {System.out.println(e.toString());}}//other codes}最近給大家找了 通用權(quán)限系統(tǒng)
資源,怎么領(lǐng)???
掃二維碼,加我微信,回復(fù):通用權(quán)限系統(tǒng)
注意,不要亂回復(fù) 沒錯(cuò),不是機(jī)器人 記得一定要等待,等待才有好東西
評(píng)論
圖片
表情
