當程序要使用某個類時,若是該類還未被加載到內存中,則系統會經過加載,鏈接,初始化來實現對這個類進行初始化 加載: 將class文件讀入內存, 併爲之建立一個Class對象; 任何類被使用時系統都會創建一個Class對象
驗證: 是否有正確的內部結構, 並和其餘類協調一致 準備: 負責爲類的靜態成員分配內存, 並設置默認初始化值 解析: 將類的二進制數據中的符號引用替換爲直接引用
初始化java
以前的new一個對象的初始化步驟
將class文件加載到內存,併爲之生成對應的Class對象 類加載器的組成 Bootstrap ClassLoader 根類加載器 引導類加載器: 負責Java核心類的加載 好比system,String等。在JDK中JRE的lib目錄下rt.jar文件中 Extension ClassLoader 擴展類加載器 負責JRE的擴展目錄中jar包的加載 在JDK中JRE的lib目錄下ext目錄 System ClassLoader 系統類加載器 負責在JVM啓動時加載來自Java命令的class文件,以及classpath環境變量所指定的jar包或類路徑
//方式1 Person p = new Person(); Class c = p.getClass(); Person p2 = new Person(); Class c2 = p2.getClass(); //false System.out.println(p == p2); //true System.out.println(c == c2); //方式2 Class c3 = Person.class; //true System.out.println(c == c3); //方式3F: Class c4=Class.forName("Person"); Class c4 = Class.forName("xx.xxxx.Person");
//public Constructor<?>[] getConstructors()獲取本類(不包括父類)全部公共(只能是public修飾的)的構造方法 Constructor[] cons=c.getConstructors(); for (Constructor con:cons){ System.out.println(con); } /**public cn.itcast_01.Person()*/
//public Constructor<?>[] getDeclaredConstructors() 獲得在本類(不包括父類)書寫的構造方法(不受訪問修飾符限制) Constructor[] cons=c.getDeclaredConstructors(); for (Constructor con:cons){ System.out.println(con); } /**protected cn.itcast_01.Person(java.lang.String,int,java.lang.String) cn.itcast_01.Person(java.lang.String,int) private cn.itcast_01.Person(java.lang.String) public cn.itcast_01.Person()*/
//獲取單個構造方法(只能是public修飾的);參數表示的是: 你要獲取的構造方法的構造參數個數及數據類型的class字節碼文件對象 //public Constructor<T> getConstructor(Class<?>... parameterTypes) Constructor cons = c.getConstructor(); Object obj=cons.newInstance(); System.out.println(obj); /**Person{name='null', age=0, address='null'}*/
//獲取單個構造方法(不受訪問修飾符的限制) //public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) Constructor cons = c.getDeclaredConstructor(String.class, int.class, String.class);//返回的構造方法對象 //Constructor類的:public T newInstance(Object... initargs)使用此Constructor對象表示的 //構造方法的聲明類的新實例,並用指定的初始化參數初始化該實例 // 暴力訪問 cons.setAccessible(true); Object obj=cons.newInstance("120", 1 ,"蛋蛋"); /**Person{name='120', age=1, address='蛋蛋'}*/
//獲取全部的成員變量(當前類及父類被public修飾的) Field[] fields=c.getFields(); //獲取全部的成員變量 (只能是本類的(不受訪問修飾符的限制)), (but excludes inherited fields)不包括從父類的 Field[] fields=c.getDeclaredFields();
Class c=Class.forName("cn.itcast_01.Person"); Constructor cons = c.getConstructor(); Object obj = cons.newInstance(); Field addressField = c.getField("address"); addressField.set(obj,"北京"); System.out.println(obj); /**Person{name='null', age=0, address='北京'}*/ Field nameField = c.getDeclaredField("name"); nameField.setAccessible(true); nameField.set(obj,"青"); System.out.println(obj); /**Person{name='青', age=0, address='北京'}*/
// 獲取本身的方法, 繼承而來的包括Object類的方法, 都只能是public修飾的 Method[] methods=c.getMethods(); //獲取本身的全部方法,包括從父類繼承的public修飾的方法 不包括Object類的 Method[] methods = c.getDeclaredMethods();
Class c = Class.forName("cn.itcast_01.Person"); Constructor cons = c.getConstructor(); Object obj = cons.newInstance(); Method method2 = c.getMethod("getString", String.class, int.class); Object objString = method2.invoke(obj, "hellojava", 100); System.out.println(objString);/**hellojava---100*/
public static void main(String[] args) throws Exception { //建立集合對象 ArrayList<Integer> arrayList = new ArrayList<>(); //添加數據 arrayList.add(120); //集合ArrayList的class文件對象 Class c = arrayList.getClass(); Method method = c.getMethod("add", Object.class); method.invoke(arrayList, "hello"); method.invoke(arrayList, "world"); method.invoke(arrayList, "java"); arrayList.add(30); // public boolean java.util.ArrayList.add(java.lang.Object) System.out.println(method); // [120, hello, world, java, 30] System.out.println(arrayList); }
public void setProperty(Object obj, String propertyName, Object value) throws Exception { //獲取字節碼文件對象 Class c=obj.getClass(); //獲取該對象的propertyName的成員變量 Field field=c.getDeclaredField(propertyName); //取消訪問檢查 field.setAccessible(true); //給對象的成員變量propertyName賦值爲指定的值 field.set(obj,value); }
JDK提供的代理只能針對接口作代理
public interface UserDao { void add(); void delete(); void update(); void find(); }
public class UserDaoImpl implements UserDao { @Override public void add() { System.out.println("添加功能"); } @Override public void delete() { System.out.println("刪除功能"); } @Override public void update() { System.out.println("修改功能"); } @Override public void find() { System.out.println("查找功能"); } }
public interface StudentDao { void login(); void regist(); }
public class StudenDaotImpl implements StudentDao { @Override public void login() { System.out.println("登陸功能"); } @Override public void regist() { System.out.println("註冊功能"); } }
public class MyInvocationHandler implements InvocationHandler{ /**目標對象*/ private Object target; public MyInvocationHandler(Object target) { this.target = target; } /** * Object invoke(Object proxy, Method method, Object[] args) * 在代理實例上處理方法調用並返回結果 * @param proxy * @param method * @param args * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("權限校驗"); Object result=method.invoke(target,args); System.out.println("日誌記錄"); // 返回的是代理對象 return result; } }
public static void main(String[] args) { UserDao ud = new UserDaoImpl(); ud.add(); ud.delete(); ud.update(); ud.find(); /*添加功能 刪除功能 修改功能 查找功能*/ System.out.println("------------"); //我要建立一個動態代理對象 Proxy類中有一個方法能夠建立動態代理對象 //public static Object newProxyInstance(ClassLoader loader, //Class<?>[] interfaces,InvocationHandler h) //對ud對象作一個代理對象 MyInvocationHandler handler = new MyInvocationHandler(ud); UserDao proxy = (UserDao) Proxy.newProxyInstance (ud.getClass().getClassLoader(), ud.getClass().getInterfaces(), handler); proxy.add(); proxy.delete(); proxy.update(); proxy.find(); /*權限校驗 添加功能 日誌記錄 權限校驗 刪除功能 日誌記錄 權限校驗 修改功能 日誌記錄 權限校驗 查找功能 日誌記錄*/ System.out.println("-------------"); StudentDao sd = new StudenDaotImpl(); MyInvocationHandler handler1 = new MyInvocationHandler(sd); StudentDao proxy1 = (StudentDao) Proxy.newProxyInstance(sd.getClass().getClassLoader(), sd.getClass().getInterfaces(), handler1); proxy1.login(); proxy1.regist(); /*權限校驗 登陸功能 日誌記錄 權限校驗 註冊功能 日誌記錄*/ }