反射

[toc]

1.Java 反射機制概述

1.1 反射的概述

  • Reflection(反射)是被視為<font color=red>動態(tài)語言</font>的關(guān)鍵坐桩,反射機制允許<font color=red>程序在執(zhí)行期</font>借助于Reflection API <font color=red>取得任何類的內(nèi)部信息</font>省容,并能<font color=red>直接操作任意對象內(nèi)部屬性方法</font>.

1.2 動態(tài)語言和靜態(tài)語言

  • 動態(tài)語言:是一類可以在運行時术陶,改變其結(jié)構(gòu)的語言痪寻。<font color=red>其實就是在運行時代碼可以根據(jù)某些條件改變自身結(jié)構(gòu)</font>
  • 靜態(tài)語言:運行時結(jié)構(gòu)不可變的語言就是靜態(tài)語言
    • Java不是動態(tài)語言螺句,但可以稱為“準(zhǔn)動態(tài)語言”,因為Java可以利用 反射機制橡类、字節(jié)碼操作 獲得類似動態(tài)語言的特性蛇尚。

1.3 Java反射機制提供的功能

  • 在運行時判斷任意一個對象所屬的類
  • 在運行時構(gòu)造任意一個類的對象
  • 在運行時判斷任意一個所具有的成員變量方法
  • 在運行時獲取泛型信息
  • 在運行時調(diào)用任意一個對象的成員變量和方法
  • 在運行時處理注解
  • 生成動態(tài)代理

1.4 代碼示例

1.4.1 Person類的代碼
public Integer id;
private String name;
public void show(){
   System.out.println("我是要成為海賊王的男人");
}
private String showNation(String nation){
        System.out.println("我的國籍"+nation);
        return nation;
}
1.4.2 通過反射,創(chuàng)建類的對象
Class clazz = Person.class;
//1.通過反射顾画,創(chuàng)建Person類的對象
Constructor cons = clazz.getConstructor(Integer.class,String.class);
Object obj = cons.newInstance(1,"qiaoba");
Person p = (Person)obj;
System.out.println(p.toString());
1.4.3 通過反射取劫,調(diào)用對象指定屬性、方法
//2.通過反射研侣,調(diào)用對象指定的屬性谱邪、方法
//調(diào)用屬性
Field id = clazz.getDeclaredField("id");
Field name = clazz.getDeclaredField("name");

id.set(p,2);

System.out.println(p.toString());

//調(diào)用方法
Method show = clazz.getDeclaredMethod("show");
show.invoke(p);
1.4.4 通過反射,還可以調(diào)用類的私有結(jié)構(gòu)
  • 調(diào)用私有的構(gòu)造器

    Constructor con1 = clazz.getDeclaredConstructor(String.class);
    con1.setAccessible(true);
    Person p1 = (Person) con1.newInstance("suolun");
    System.out.println(p1);
    
  • 調(diào)用私有的屬性

    Field name = clazz.getDeclaredField("name");
    name.setAccessible(true);
    name.set(p1, "山治");
    System.out.println(p1);
    
  • 調(diào)用私有的方法

    Method showNation = clazz.getDeclaredMethod("showNation", String.class);
    showNation.setAccessible(true);
    String nation = (String)showNation.invoke(p1, "中國"); //相當(dāng)于p1.showNation("中國")
    System.out.println(nation);
    

1.5 反射機制與面向?qū)ο笾械姆庋b性是不是很矛盾的庶诡?如何看到兩個技術(shù)惦银?

1.6 通過直接new 的方式或反射的方式都可以調(diào)用公共的結(jié)構(gòu),開發(fā)中到底用哪個灌砖?

  • 建議:直接new的方式
  • 什么時候會使用璧函? 反射的方式。 反射的特征:動態(tài)性

2.理解Class類并<font color=red>獲取Class實例</font>

2.1關(guān)于java.lang.Class 類的理解

2.1.1類的加載過程
  • 程序經(jīng)過 javac.exe 命令以后基显,會生成一個或多個字節(jié)碼文件(.class)結(jié)尾
  • 接著使用 java.exe 命令對某個字節(jié)碼文件進行解釋運行蘸吓。相當(dāng)于將某個字節(jié)碼文件加載到內(nèi)存中。此過程就稱為 類的加載撩幽。
  • 加載到內(nèi)存中的類库继,我們稱為運行時類此運行時類窜醉,就作為Class的一個實例宪萄。
  • 也就是說,Class 的實例就對應(yīng)著一個運行時類榨惰。
  • 加載到內(nèi)存中的運行時類拜英,會緩存一定的時間,在此時間之內(nèi)琅催,我們可以通過不同的方式來獲取此運行時類居凶。

2.2 哪些類型可以有 Class 對象?

  • class:外部類藤抡,成員(成員內(nèi)部類侠碧,靜態(tài)內(nèi)部類),局部內(nèi)部類缠黍,匿名內(nèi)部類

  • interface:接口

  • enum: 枚舉

  • annotation: 注解 @interface

  • primitive type:基本數(shù)據(jù)類型

  • void

    Class c1 = Object.class;
    Class c2 = Comparable.class;
    Class c3 = String[].class;
    Class c4 = int[][].class;
    Class c5 = ElementType.class;
    Class c6 = Override.class;
    Class c7 = int.class;
    Class c8 = void.class;
    Class c9 = Class.class;
    
    int[] a = new int[10];
    int[] b = new int[100];
    
    Class c10 = a.getClass();
    Class c11 = b.getClass();
    

2.3 <font color=red>獲取Class 實例</font>

2.3.1 方式一:調(diào)用運行時類的屬性:.class
Class<Person> clazz1 = Person.class;
或
Class clazz = Person.class;
2.3.2 方式二:通過運行時類的對象弄兜,調(diào)用getClass()
Person p1 = new Person();
Class clazz2 = p1.getClass();
2.3.3 方式三:調(diào)用Class的靜態(tài)方法:forName(String classPath)
Class clazz3 = Class.forName("com.lut.java.Person");
2.3.4 方式四:使用類的加載器: ClassLoader
ClassLoader classLoader = ReflectionTest.class.getClassLoader();
Class clazz4 = classLoader.loadClass("com.lut.java.Person");

3.類的加載與ClassLoader的理解

3.1 類的加載過程

3.1.1 加載
  • 將class 字節(jié)碼文件加載到內(nèi)存中,并將靜態(tài)數(shù)據(jù)轉(zhuǎn)換為方法區(qū)的運行時的數(shù)據(jù)結(jié)構(gòu),然后生成一個代表這個類的java.lang.Class 對象替饿。所有需要訪問和使用類數(shù)據(jù)只能通過這個Class對象语泽。
3.1.2 鏈接:將Java類 的二進制代碼合并到JVM的運行狀態(tài)之中的過程。
  • 驗證:確保加載類信息符合JVM規(guī)范
  • 準(zhǔn)備:正式為類變量(static) 分配內(nèi)存并設(shè)置類變量默認初始值的階段盛垦,
  • 解析:虛擬機常量池內(nèi)的符號引用(常量名) 替換為 直接引用(地址)的過程湿弦。
3.1.3 初始化
  • 執(zhí)行類構(gòu)造器< clinit >方法的過程。類構(gòu)造器<clinit> () 方法是由編譯器自動收集類中所有類變量的賦值動作和靜態(tài)代碼塊中的語句合并產(chǎn)生腾夯。(類構(gòu)造器是構(gòu)造類信息的,不是構(gòu)造該類對象的構(gòu)造器)蔬充。
  • 當(dāng)初始化一個類時蝶俱,如果其父類還為初始化,則需要先觸發(fā)其父類的初始化饥漫。
  • 虛擬機會保證一個類的<clinit> 方法在多線程環(huán)境被正確加鎖和同步

3.2 類的加載器的作用

  • 將class字節(jié)碼文件加載到內(nèi)存中榨呆,并將靜態(tài)數(shù)據(jù)轉(zhuǎn)換為方法區(qū)的運行時的數(shù)據(jù)結(jié)構(gòu),在中生成一個代表這個類的java.lang.Class 對象庸队,作為方法區(qū)的類數(shù)據(jù)的訪問入口积蜻。

3.3類緩存

  • 某個類被加載到加載器中,它將維持加載(緩存)一段時間彻消。不過JVM垃圾回收機制可以回收這些Class對象竿拆。

3.4 ClassLoader

3.4.1 類加載器(ClassLoader)的分類
  • 引導(dǎo)類加載器:負責(zé)Java平臺的核心庫,該加載器無法直接獲取

  • 擴展類加載器:負責(zé)jar/lib/ext 目錄下的jar包或指定目錄下的jar包 宾尚,裝入工作庫

  • 系統(tǒng)類加載器:負責(zé)java-classpath 目錄下的類丙笋,與jar包裝入工作,是最常用的類

    //對于自定義類煌贴,使用系統(tǒng)類加載器進行加載
    ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
    
    //調(diào)用系統(tǒng)類加載器的getParent():獲取擴展類加載器
    ClassLoader classLoader1 = classLoader.getParent();
    
    //調(diào)用擴展類加載器的getParent():無法獲取引導(dǎo)類加載器
    ClassLoader classLoader2 = classLoader1.getParent(); //null
    
3.4.2 <font color=red>使用ClassLoader 加載配置文件</font>
  • 讀取配置文件的方式一:使用輸入流的方式
Properties pros = new Properties();
//此時的文件默認在當(dāng)前的module下
FileInputStream fis = new FileInputStream("jdbc.properties");

//讀取在module下的src下的文件
//FileInputStream fis = new FileInputStream("src\\jdbc1.properties");

pros.load(fis);

String user = pros.getProperty("user");
String password = pros.getProperty("password");

System.out.println("user="+user+",password="+password);
  • 讀取配置文件的方式二:使用ClassLoader
  • 配置文件默認識別為:當(dāng)前module的src下
 Properties pros = new Properties();

//讀取配置文件的方式二:使用ClassLoader
//配置文件默認識別為:當(dāng)前module的src下

ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
InputStream is = classLoader.getResourceAsStream("jdbc1.properties");

pros.load(is);

String user = pros.getProperty("user");
String password = pros.getProperty("password");

System.out.println("user="+user+",password="+password);

4.<font color=red>創(chuàng)建運行時類的對象</font>

4.1通過反射創(chuàng)建對應(yīng)的運行時類的對象

Class<Person> clazz = Person.class;
Person obj = clazz.newInstance();

Class clazz1 = Person.class;
Person obj1 = (Person) clazz1.newInstance();

4.2 new Instance() :調(diào)用此方法御板,創(chuàng)建對應(yīng)的運行時類的對象,內(nèi)部調(diào)用了運行時類的空參構(gòu)造器牛郑。

4.2.1 要想此方法正常的創(chuàng)建運行時類的對象怠肋,要求
  • 運行時類必須提供空參構(gòu)造器
  • 空參構(gòu)造器的訪問權(quán)限必須得夠。通常設(shè)置為public
4.2.2 在javabean中要求提供一個public 的空參構(gòu)造器淹朋。原因:
  • 便于通過反射笙各,創(chuàng)建運行時類
  • 便于子類繼承此運行時類時,默認調(diào)用super() 時瑞你,保證父類有此構(gòu)造器酪惭。

4.3 舉例體會反射的動態(tài)性

@Test
public void test2() throws  Exception{
    for (int i = 0; i < 100 ; i++) {
        int  num = new Random().nextInt(3);
        String classPath="";

        switch (num){
            case 0 :
                classPath="java.util.Date";
                break;

            case 1:
                classPath="java.lang.Object";
                break;

            case 2:
                classPath="com.lut.java.Person";
                break;
        }

        Object obj = getInstance(classPath);
        System.out.println(obj);
    }

}

public Object getInstance(String classpath) throws Exception{
    Class clazz = Class.forName(classpath);
    return clazz.newInstance();
}

5.獲取運行時類的完整結(jié)構(gòu)

5.1 獲取屬性結(jié)構(gòu)

5.1.1getFields()
  • 獲取當(dāng)前運行是類及其父類中聲明為public 訪問權(quán)限的屬性

    Field[] fields = clazz.getFields();
    
    for (Field field : fields) {
        System.out.println(field);
    }
    
5.1.2 getDeclaredFields()
  • 獲取當(dāng)前運行時類中聲明的所有屬性。(不包含父類中聲明的屬性)

    Field[] declaredFields = clazz.getDeclaredFields();
    for (Field declaredField : declaredFields) {
        System.out.println(declaredField);
    }
    
5.1.3 獲取權(quán)限修飾符
int modifiers = field.getModifiers();
System.out.println(Modifier.toString(modifiers));
5.1.4 獲取數(shù)據(jù)類型
Class type = field.getType();
System.out.print(type.getName()+"\t");
5.1.5 獲取變量名
String fName = field.getName();
System.out.println(fName);

5.2 獲取運行時類的方法結(jié)構(gòu)

5.2.1 getMethods():獲取當(dāng)前運行時類及其所有父類中聲明為public 權(quán)限的方法
Class clazz = Person.class;

Method[] methods = clazz.getMethods();
for (Method method : methods) {
    System.out.println(method);

}
5.2.2 getDeclaredMethods(): 獲取當(dāng)前運行時類中聲明的所有方法者甲。(不包含父類中聲明的方法)
Method[] dms = clazz.getDeclaredMethods();
for (Method dm : dms) {
    System.out.println(dm);
}
5.2.3 getAnnotations():獲取方法的聲明的注解
Annotation[] annos = dm.getAnnotations();
for (Annotation anno : annos) {
    System.out.println(anno);
}
5.2.4 getModifers(): 獲取權(quán)限修飾符
System.out.print(Modifier.toString(dm.getModifiers()) + "\t");
5.2.5 getReturnType(): 獲取返回類型
System.out.print(dm.getReturnType() + "\t");
5.2.6 getName(): 獲取方法名
System.out.println(dm.getName());
5.2.7 getParameterTypes(): 獲取形參列表
Class[] parameterTypes = dm.getParameterTypes();
if(!(parameterTypes == null && parameterTypes.length == 0)){
    for (int i = 0; i <parameterTypes.length ; i++) {
        if(i == parameterTypes.length - 1) {
            System.out.print(parameterTypes[i].getName() + " args_" + i );

            break;
        }
        System.out.print(parameterTypes[i].getName() + " args_" + i + ",");
    }
}
5.2.8 getExceptionTypes(): 獲取拋出的異常
lass[] ets = dm.getExceptionTypes();
if(ets.length > 0){
    System.out.println("throws ");
    for (int i = 0; i < ets.length ; i++) {
        if(i == ets.length - 1){
            System.out.println(ets[i].getName());
            break;
        }
        System.out.println(ets[i].getName() +",");
    }
}

5.3 獲取運行時類的構(gòu)造器結(jié)構(gòu)

5.3.1 getConstructors(): 獲取當(dāng)前運行時類中聲明為 public 的構(gòu)造器
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {
    System.out.println(constructor);

}
5.3.2 getDeclaredConstructors(): 獲取當(dāng)前運行時類中聲明的所有的構(gòu)造器
Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
for (Constructor declaredConstructor : declaredConstructors) {
    System.out.println(declaredConstructor);

}

5.4 獲取運行時類的父類 getSuperclass()

Class superclass = clazz.getSuperclass();
System.out.println(superclass);

5.5 獲取運行時類的帶泛型的父類 getGenericeSuperclass()

Type genericSuperclass = clazz.getGenericSuperclass();
System.out.println(genericSuperclass);

5.6 獲取運行時類的帶泛型的父類的泛型

Class clazz = Person.class;

Type genericSuperclass = clazz.getGenericSuperclass();
ParameterizedType paramType =(ParameterizedType) genericSuperclass;
//獲取泛型的類型
Type[] actualTypeArguments = paramType.getActualTypeArguments();
//      System.out.println(actualTypeArguments[0].getTypeName()); 
//或
        System.out.println(((Class)actualTypeArguments[0]).getName());
 

5.7 獲取運行時類實現(xiàn)的接口

5.7.1 獲取運行時類實現(xiàn)的接口
Class clazz = Person.class;

Class[] interfaces = clazz.getInterfaces();

for (Class c : interfaces) {
    System.out.println(c);

}
5.7.2獲取運行時類實現(xiàn)的父類的接口
Class[] interfaces1 = clazz.getSuperclass().getInterfaces();
for (Class aClass : interfaces1) {
    System.out.println(aClass);

}

5.8 獲取運行時類所在包

Class clazz = Person.class;

Package aPackage = clazz.getPackage();
System.out.println(aPackage);

5.9 獲取運行時類聲明的注解

Class clazz = Person.class;

Annotation[] annotations = clazz.getAnnotations();
for (Annotation annotation : annotations) {
    System.out.println(annotation);
}

6.<font color=red>調(diào)用運行時類的指定結(jié)構(gòu)</font>

6.1如何操作運行時類中指定的屬性

6.1.1保證當(dāng)前屬性是可訪問的 setAccessible(true);
6.1.2 操作運行類中public的屬性(不理想)
 Class clazz = Person.class;

//創(chuàng)建運行時類的對象
Person p  = (Person) clazz.newInstance();

 //獲取指定的屬性
Field id = clazz.getField("id") ;

//設(shè)置當(dāng)前屬性的值
// set(): 參數(shù)1:指明設(shè)置那個對象的屬性   參數(shù)2:將此屬性值設(shè)置為多少
id.set(p, 1001);

/*
獲取當(dāng)前屬性的值
get():參數(shù)1:獲取那個對象的屬性值
 */
int pId = (int) id.get(p);
System.out.println(pId);
6.1.3 操作運行時類中的指定屬性(<font color=red>掌握</font>)
  • getDeclaredField(String fieldName):獲取運行時類中指定變量名的屬性
  • setAccessible(true) 保證當(dāng)前屬性是可訪問的
  • 設(shè)置當(dāng)前屬性的值 set(): 參數(shù)1:指明設(shè)置那個對象的屬性 參數(shù)2:將此屬性值設(shè)置為多少
  • 獲取當(dāng)前屬性的值 get():參數(shù)1:獲取那個對象的屬性值
Class clazz = Person.class;

//創(chuàng)建運行時類的對象
Person p = (Person) clazz.newInstance();

//1. getDeclaredField(String fieldName):獲取運行時類中指定變量名的屬性
Field name = clazz.getDeclaredField("name");

//2. 保證當(dāng)前屬性是可訪問的
name.setAccessible(true);

//3. 獲取春感、設(shè)置指定對象的此屬性值
name.set(p,"Tom");

System.out.println(name.get(p));

6.2 操作運行時類的中的指定方法(<font color=red>掌握</font>)

6.2.1 獲取指定的某個方法 getDeclaredMethod(): 參數(shù)1:指明獲取方法的名稱, 參數(shù)2:指明獲取方法的形參列表
6.2.2 invoke(): 參數(shù)1:方法的調(diào)用者 參數(shù)2 : 給方法形參賦值的實參
  • invoke() 的返回值即為對應(yīng)類中調(diào)用的方法的返回值
6.2.3 獲取運行時類的非靜態(tài)方法
Class clazz = Person.class;

Person p = (Person)clazz.newInstance();

//1.獲取指定的某個方法
Method show = clazz.getDeclaredMethod("show", String.class);

//2.保證當(dāng)前方法是可訪問的
show.setAccessible(true);

//3.調(diào)用invoke
//invoke() 的返回值即為對應(yīng)類中調(diào)用的方法的返回值
Object returnValue = show.invoke(p, "CHN"); //String nation = p.show("CHN");
System.out.println(returnValue);
6.2.4 獲取運行時類的靜態(tài)方法
Method showDesc = clazz.getDeclaredMethod("showDesc");
showDesc.setAccessible(true);

// Object returnVal = showDesc.invoke(Person.class);
//或
Object returnVal = showDesc.invoke(null);
System.out.println(returnVal);

6.3 調(diào)用運行時類的構(gòu)造器

6.3.1獲取指定的構(gòu)造器 getDeclaredConstructro():參數(shù):指明構(gòu)造器的參數(shù)列表
Class clazz = Person.class;

//1. 獲取指定的構(gòu)造器
//getDeclaredConstructro():參數(shù):指明構(gòu)造器的參數(shù)列表
Constructor constructor = clazz.getDeclaredConstructor(String.class);

//2. 保證此構(gòu)造器是可訪問的
constructor.setAccessible(true);

//3. 調(diào)用此構(gòu)造器創(chuàng)建運行時類的對象
Person person = (Person)constructor.newInstance("Tom");

System.out.println(person);

7.反射的應(yīng)用:動態(tài)代理

7.1 代理設(shè)計模式的原理:

  • 使用一個代理將對象包裝起來,然后用代理對象取代原始對象鲫懒,任何對原始對象的調(diào)用都要通過代理嫩实。代理對象決定是否以及何時將方法調(diào)用轉(zhuǎn)到原始對象上。

7.2靜態(tài)代理的實例

7.2.1特點:代理類和被代理類在編譯期間窥岩,就確定下來了
7.2.2 代碼
interface ClothFactory{

    void produceCloth();

}

class ProxyClothFactory implements ClothFactory{
    private ClothFactory clothFactory;//用被代理類對象進行實例化

    public ProxyClothFactory(ClothFactory clothFactory){
        this.clothFactory = clothFactory;
    }

    @Override
    public void produceCloth() {
        System.out.println("代理工廠做一些準(zhǔn)備工作");

        clothFactory.produceCloth();

        System.out.println("代理工廠做一些后續(xù)的收尾工作");
    }
}

// 被代理類
class NikeClothFactory implements ClothFactory{

    @Override
    public void produceCloth() {
        System.out.println("Nike 工廠生產(chǎn)一批運動服");
    }
}

7.3 動態(tài)代理


interface  Human{
    String getBelief();

    void eat(String food);
}

//被代理類
class SuperMan implements Human{


    @Override
    public String getBelief() {
        return "I believe I can fly!";
    }

    @Override
    public void eat(String food) {
        System.out.println("我喜歡吃"+food);
    }


}

/*
動態(tài)代理實現(xiàn)需要解決的問題:
① 如何根據(jù)加載到內(nèi)存中的被代理類甲献,動態(tài)的創(chuàng)建一個代理類及其對象
② 當(dāng)通過被代理類的對象調(diào)用方法時,如何動態(tài)的去調(diào)用被代理類中的同名方法
 */

class ProxyFactory{

    //調(diào)用此方法颂翼,返回一個代理類的對象晃洒。

    public static Object getProxyInstance(Object obj){//obj:被代理類的對象
        MyInvocationHandler handler = new MyInvocationHandler();

        handler.bind(obj);

        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(), handler);


    }
}

class MyInvocationHandler implements InvocationHandler{

    private Object obj;//賦值時肩袍,也需要使用被代理類的對象進行賦值

    public void bind(Object obj){ //obj: 被代理類的對象
        this.obj = obj;
    }
    //當(dāng)我們通過代理類的對象鳖擒,調(diào)用方法a時,就會自動調(diào)用如下方法:invoke
    //將被代理類要執(zhí)行的方法a的功能就聲明在invoke()中
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //method:即為代理類對象調(diào)用的方法颅崩,此方法也就作為了被代理類對象要調(diào)用的方法
        //obj:被代理類的對象
        Object returnValue =  method.invoke(obj,args);
        //上述方法的返回值就作為當(dāng)前類中到的invoke()的返回值
        return returnValue;
    }
}


public class ProxyTest {

    public static void main(String[] args) {
        SuperMan superMan = new SuperMan();

        //proxyInstance: 代理類的對象

        Human proxyInstance  = (Human) ProxyFactory.getProxyInstance(superMan);

        //當(dāng)通過代理類對象調(diào)用方法是呻疹,會自動調(diào)用被代理類中的同名方法
        String belief = proxyInstance.getBelief();
        System.out.println(belief);
        proxyInstance.eat("四川麻辣燙");

    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吃引,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子刽锤,更是在濱河造成了極大的恐慌镊尺,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件并思,死亡現(xiàn)場離奇詭異庐氮,居然都是意外死亡,警方通過查閱死者的電腦和手機纺荧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門旭愧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人宙暇,你說我怎么就攤上這事输枯。” “怎么了占贫?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵桃熄,是天一觀的道長。 經(jīng)常有香客問我型奥,道長瞳收,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任厢汹,我火速辦了婚禮螟深,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘烫葬。我一直安慰自己界弧,他們只是感情好凡蜻,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著垢箕,像睡著了一般划栓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上条获,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天忠荞,我揣著相機與錄音,去河邊找鬼帅掘。 笑死委煤,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的锄开。 我是一名探鬼主播素标,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼萍悴!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起寓免,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤癣诱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后袜香,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體撕予,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年蜈首,在試婚紗的時候發(fā)現(xiàn)自己被綠了实抡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡欢策,死狀恐怖吆寨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情踩寇,我是刑警寧澤啄清,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站俺孙,受9級特大地震影響辣卒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜睛榄,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一荣茫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧场靴,春花似錦啡莉、人聲如沸港准。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽叉趣。三九已至,卻和暖如春该押,著一層夾襖步出監(jiān)牢的瞬間疗杉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工蚕礼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留烟具,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓奠蹬,卻偏偏與公主長得像朝聋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子囤躁,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 主要介紹以下幾方面內(nèi)容 理解 Class 類理解 Java 的類加載機制學(xué)會使用 ClassLoader 進行類加...
    dinel閱讀 673評論 0 1
  • java反射主要從以下幾個方面理解 理解 Class 類 理解 Java 的類加載機制 學(xué)會使用 ClassLoa...
    境里婆娑閱讀 11,586評論 0 11
  • Java反射的功能非常之強大腊尚,能夠深入的理解其思想,對自己的開發(fā)能力將有非常大的提高满哪。 反射概述 Reflecti...
    3829a40ab7b9閱讀 272評論 0 0
  • 反射庫提供了一個非常豐富且精心設(shè)計的工具集婿斥,以便能夠動態(tài)編寫能夠操縱Java代碼的程序。這項功能被大量應(yīng)用于Jav...
    Steven1997閱讀 626評論 0 2
  • Java的Class類是java反射機制的基礎(chǔ),通過Class類我們可以獲得關(guān)于一個類的相關(guān)信息,下面我們來了解一...
    jiangmo閱讀 919評論 0 3