一、註解
1、
二、反射
1、動態語言
1、動態語言:程序運行時,可以改變程序結構或變量類型。
eg:Python、ruby、javascript。
function test(){
var s = "var a=3;var b=5;alert(a+b);";
eval(s);
}
c、c++、java不是動態語言,但是java有一定動態性,我們可以利用反射、字節碼操作獲得類似動態語言的特性。
反射機制(reflection):指的是可以於運行時加載、探知、使用編譯期間完全未知的類。
一個類只對應一個反射對象,即java -> class。
Class<?> clazz = Class.forName("com.hx.test.User");
Class strClass = String.class;
Class c = "com.hx.test.User".getClass();
以上三種都可以獲取反射對象,第一種最常用。
可以獲取class、interface、enum、annotation、primitive、type、void對應的class。
api:
Class<?> clazz = Class.forName("com.hx.test.User");
clazz.getName();//獲得包名+類名
clazz.getSimpleName();//獲得類名
Field[] fields = clazz.getFields();//只有public的屬性可以被獲得
Field[] fields = clazz.getDeclaredFields();//獲得所有屬性
Method[] methods = clazz.getDeclaredMethods();//獲得所有方法
Method method1 = clazz.getDeclaredMethods("getUserName", null);//獲得指定方法,該方法無參數所有傳入null
Method method2 = clazz.getDeclaredMethods("setUserName", String.class);//如果方法有參數,獲得指定方法並傳入參數類型的class對象
Constructor[] constructors = clazz.getDeclaredConstructors();//獲得所有構造方法
通過反射調用對象
Class clazz = Class.forName("com.hx.test.User");
User user = clazz.newInstance();//是調用了無參構造方法,所以要注意被調用的類要有無參構造方法
Constructor<User> constructor = clazz.getDeclaredConstructor(String.class, int.calss);
User user2 = constructor.newInstance("張三", 18);//調用指定有參構造函數,並傳遞實際參數進行調用
//可以直接用獲得的類調用其方法,也可以用反射調用其方法實現動態調用。
User user3 = clazz.newInstance();
Method method = clazz.getDeclaredMethods("setUserName", String.class);
method.invoke(user3, "李四");
User user4 = clazz.newInstance();
Field field = clazz.getDeclaredFields("userName");
field.setAccessible(true);//這個屬性不需要做安全檢查了,可以直接訪問private修飾的屬性或方法
field.set(user4, "王五");//通過反射直接寫屬性