Java核心技術(shù)之反射(詳細(xì)API和MyBatis簡(jiǎn)單實(shí)現(xiàn))

我們平時(shí)調(diào)用方法或者創(chuàng)建一個(gè)類的實(shí)例都是在代碼之中寫死的,有沒有什么辦法例如就是傳一個(gè)方法名進(jìn)一個(gè)來,然后就能動(dòng)態(tài)調(diào)用這個(gè)方法呢,諸如此類的在程序運(yùn)行時(shí)能夠獲取某個(gè)類自身的所有信息在java當(dāng)中被稱之為反射,反射是java的核心技術(shù),各種框架當(dāng)中無一不用到反射,可以說程序當(dāng)中自動(dòng)化功能的實(shí)現(xiàn)都需要反射去實(shí)現(xiàn).

Java.lang.reflect(反射包)
包中包括以下類:

  1. Class :代表一個(gè)類,可以獲取一個(gè)類中的所有信息

  2. Field :代表類的成員變量

  3. Method :代表類的方法

  4. Constructor: 代表類的構(gòu)造方法

  5. Array : 提供了動(dòng)態(tài)創(chuàng)建數(shù)組,以及訪問數(shù)組的元素的靜態(tài)方法

  6. Proxy : 提供用于創(chuàng)建動(dòng)態(tài)代理類和實(shí)例的靜態(tài)方法,它還是由這些方法創(chuàng)建的所有動(dòng)態(tài)代理類的超類

1.Class

每個(gè)java類運(yùn)行時(shí)都在JVM里表現(xiàn)為一個(gè)Class對(duì)象,可通過類名.class,類對(duì)象.getClass(),Class.forName("全類名")獲取class對(duì)象

方法名中帶有Declared的方法表示本類的信息,無論公私有屬性或函數(shù)

  1. String getName():獲取全類名(包名和類名)
  1. String getSimpleName() :獲取類名
  2. Class<?> forName(String className) :根據(jù)全類名獲取Class對(duì)象
  3. T newInstance():根據(jù)Class對(duì)象新建一個(gè)對(duì)象(類中必須要有一個(gè)無參的構(gòu)造函數(shù))
  4. ClassLoader getClassLoader():獲得類的類加載器姨伤。
  5. Class getSuperclass():獲取類的父類刹泄,繼承了父類則返回父類觉既,否則返回java.lang.Object.
  6. boolean isEnum() :判斷是否為枚舉類型
  7. boolean isArray() :判斷是否為數(shù)組類型
  8. boolean isPrimitive() :判斷是否為基本類型
  9. boolean isAnnotation() :判斷是否為注解類型
  10. Package getPackage() :反射中獲得package
  11. int getModifiers() : 反射中獲得修飾符對(duì)應(yīng)的數(shù)字(若要轉(zhuǎn)換為public,可用Modifier.toString(Domain.class.getModifiers()))
  12. Field getField(String name):反射中獲得域成員

14 .Field[] getFields() :獲得域數(shù)組成員
15 . Method[] getMethods() :獲得所有共有方法
16 . Method getDeclaredMethod(String name, Class<?>... parameterTypes):加個(gè)Declared代表本類羊异,繼承穆律,父類均不包括床佳。而且包括所有公私有方法.
17 .Constructor<?>[] getConstructors() :獲得所有的構(gòu)造函數(shù)
18 .Class<?> getComponentType :如果是數(shù)組Class對(duì)象,則可通過此方法得到數(shù)組類型,如果不是數(shù)組用此方法返回為null
19 .Annotation getAnnotation(Class<A> annotationClass)
如果存在這樣的注解桥胞,則返回該元素的指定類型的注解恳守,否則返回null。
20 .Annotation[] getAnnotation()
21 .InputStream getResourceAsStream(String path) : path 不以’/'開頭時(shí)默認(rèn)是從此類所在的包下取資源贩虾,以’/'開頭則是從ClassPath根下獲取催烘。其只是通過path構(gòu)造一個(gè)絕對(duì)路徑,最終還是由ClassLoader獲取資源
22 .Class<?> getSuperclass() :返回父類的Class對(duì)象
23 .boolean isassignablefrom(Class<?> cls)
用來校驗(yàn)一個(gè)類是否參數(shù)中的Class實(shí)現(xiàn)指定的父類
24 .boolean isInstance(Object obj)該方法和instanceof運(yùn)算符作用等價(jià),但是instanceof是對(duì)象instanceof 類,檢查左邊的被測(cè)試對(duì)象 是不是 右邊類或接口的 實(shí)例化缎罢,而isInstance方法是 類.class.isInstance(對(duì)象),obj是被測(cè)試的對(duì)象伊群,如果obj是調(diào)用這個(gè)方法的class或接口 的實(shí)例考杉,則返回true
25 .boolean isMemberClass() :判斷當(dāng)前類是否成員類

2. Field

可以通過class的getDeclaredField(String name),getDeclaredFields(),getField(String name),getFields()獲取,通過Field的方法可以獲取舰始、設(shè)置屬性的值崇棠,并能獲取屬性的注解、字段的聲明類型蔽午。

  1. Class<?> getType(): 獲取屬性聲明時(shí)類型對(duì)象
  1. Type getGenericType() : 獲取屬性聲明時(shí)類型的Type對(duì)象
  2. String getName() : 獲取屬性聲明時(shí)名字
  3. getAnnotations() : 獲得這個(gè)屬性上所有的注釋
  4. int getModifiers() : 獲取屬性的修飾符對(duì)應(yīng)的值
  5. boolean isSynthetic() : 判斷這個(gè)屬性是否是 復(fù)合類
  6. get(Object obj) : 取得obj對(duì)象這個(gè)Field上的值(不通過get方法獲取,需要使用setAccessible(true)禁用訪問控制權(quán)限)
  7. set(Object obj, Object value) : 向obj對(duì)象的這個(gè)Field設(shè)置新值value(不通過set方法設(shè)置,需要使用setAccessible(true)禁用訪問控制權(quán)限)
  8. setAccessible(boolean flag) 禁用/開啟訪問控制權(quán)限

3. Method

描述類的成員方法易茬,Method 提供關(guān)于類或接口上單獨(dú)某個(gè)方法(以及如何訪問該方法)的信息。所反映的方法可能是類方法或?qū)嵗椒ǎòǔ橄蠓椒ǎ┘袄稀ethod 允許在匹配要調(diào)用的實(shí)參與底層方法的形參時(shí)進(jìn)行擴(kuò)展轉(zhuǎn)換可以通過class的getDeclaredMethod(String name, Class<?>... parameterTypes) 抽莱,getDeclaredMethods() ,getMethod(String name,Class<?>... parameterTypes)骄恶,getMethods() 獲取食铐,通過Method的invoke方法去執(zhí)行,獲取返回值僧鲁,也可以獲取方法注解虐呻、 返回值類型等号俐。

方法中存在Generic的,就表示返回值返回Type類型

  1. getAnnotation(Class<T> annotationClass) :如果存在該元素的指定類型的注釋更振,則返回這些注釋,否則返回 null丹莲。
  1. Annotation[] getDeclaredAnnotations() :返回直接存在于此元素上的所有注釋
  2. Class<?> getDeclaringClass() :返回當(dāng)前方法的類Class對(duì)象
  3. Class<?>[] getExceptionTypes() :返回 Class 對(duì)象的數(shù)組春寿,這些對(duì)象描述了聲明將此 Method 對(duì)象表示的底層方法拋出的異常類型
  4. Type[] getGenericExceptionTypes() :返回 Type 對(duì)象數(shù)組朗涩,這些對(duì)象描述了聲明由此 Method 對(duì)象拋出的異常
  5. Type[] getGenericParameterTypes() :按照聲明順序返回 Type 對(duì)象的數(shù)組,這些對(duì)象描述了此 Method 對(duì)象所表示的方法的形參類型的
  6. Class<?>[] getParameterTypes() :按照聲明順序返回 Class 對(duì)象的數(shù)組绑改,這些對(duì)象描述了此 Method 對(duì)象所表示的方法的形參類型
  7. Type getGenericReturnType() :返回表示由此 Method 對(duì)象所表示方法的正式返回類型的 Type 對(duì)象谢床。
    Class<?> getReturnType() :返回一個(gè) Class 對(duì)象,該對(duì)象描述了此 Method 對(duì)象所表示的方法的正式返回類型
  8. int getModifiers() 以整數(shù)形式返回此 Method 對(duì)象所表示方法的 Java 語言修飾符
  9. String getName() :以 String 形式返回此 Method 對(duì)象表示的方法名稱厘线。
  10. Object invoke(Object obj, Object... args) :對(duì)帶有指定參數(shù)的指定對(duì)象調(diào)用由此 Method 對(duì)象表示的底層方法
  11. boolean isVarArgs(): 如果將此方法聲明為帶有可變數(shù)量的參數(shù)识腿,則返回 true;否則造壮,返回 false

4. Constructor

Constructor是對(duì)構(gòu)造方法的聲明描述渡讼,Constructor 提供關(guān)于類的單個(gè)構(gòu)造方法的信息以及對(duì)它的訪問權(quán)限。Constructor
允許在將實(shí)參與帶有底層構(gòu)造方法的形參的 newInstance() 匹配時(shí)進(jìn)行擴(kuò)展轉(zhuǎn)換耳璧∠跞可以通過class的getConstructor(Class<?>... parameterTypes) ,getConstructors()楞抡,getDeclaredConstructor(Class<?>... parameterTypes) 伟众,getDeclaredConstructors() 獲取。通過Constructor可以獲取注解召廷,參數(shù)類型等凳厢,并通過newInstance(Object... initargs) 創(chuàng)建類實(shí)例账胧。

具體的方法跟上面的大同小異,通過名字都可以猜出來什么意思了

5. Array

Array 類提供了動(dòng)態(tài)創(chuàng)建和訪問 Java 數(shù)組的方法。允許在執(zhí)行 get 或 set 操作期間進(jìn)行擴(kuò)展轉(zhuǎn)換先紫≈文啵可以通過class的isArray方法判定此 Class 對(duì)象是否表示一個(gè)數(shù)組類,getComponentType返回表示數(shù)組類型的 Class遮精。通過newInstance初始化數(shù)組居夹。

  1. static Object newInstance(Class cls,int array_length) :創(chuàng)建一個(gè)數(shù)組
  1. 訪問動(dòng)態(tài)數(shù)組元素的方法和通常有所不同,它的格式如下所示本冲,注意該方法返回的是一個(gè)Object對(duì)象
    Array.get(arrayObject, index)

  2. 為動(dòng)態(tài)數(shù)組元素賦值的方法也和通常的不同准脂,它的格式如下所示, 注意最后的一個(gè)參數(shù)必須是Object類型
    Array.set(arrayObject, index, object)

  3. int getLength(Object obj) 返回?cái)?shù)組的長度

6. Proxy(代理類)

Proxy 提供用于創(chuàng)建動(dòng)態(tài)代理類和實(shí)例的靜態(tài)方法檬洞,它還是由這些方法創(chuàng)建的所有動(dòng)態(tài)代理類的父類

  1. static Object newProxyInstance(ClassLoader classLoader,Class<?>[] interfaceArr,InvocationHandler h) :方法上有三個(gè)參數(shù),第一個(gè)指定一個(gè)類加載器,第二個(gè)參數(shù)為,被代理類實(shí)現(xiàn)的接口數(shù)組,第三個(gè)是代理類

創(chuàng)建一個(gè)動(dòng)態(tài)代理的步驟(例如要代理的類名為Car,代理類為MyProxy):

1.為被代理類創(chuàng)建一個(gè)接口,名字為BaseCar

public interface BaseCar {
    void run();
}

**2.被代理類實(shí)現(xiàn)BaseCar接口,并重寫B(tài)aseCar中的方法 **

public class Car implements BaseCar {

    @Override
    public void run() {
        
        System.out.println("汽車啟動(dòng)");
    }

}

3.MyProxy代理類實(shí)現(xiàn)InvocationHandler接口,并重寫invoke方法,記得要以BaseCar作為成員變量,還有給BseCar初始化,因?yàn)閙ethod.invoke要用到BaseCar的實(shí)例

public class MyProxy implements InvocationHandler {

    private BaseCar baseCar;

    public MyProxy(BaseCar baseCar) {
        super();
        this.baseCar = baseCar;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("汽車啟動(dòng)前");
        Object invoke = method.invoke(baseCar, args);
        System.out.println("汽車啟動(dòng)后");
        return invoke;
    }

}

可以看到invoke方法有三個(gè)參數(shù):

  1. 動(dòng)態(tài)代理類的引用狸膏,通常情況下不需要它。但可以使用getClass()方法添怔,得到proxy的Class類從而取得實(shí)例的類信息湾戳,如方法列表,annotation等广料。
  1. 方法對(duì)象的引用砾脑,代表被動(dòng)態(tài)代理類調(diào)用的方法。從中可得到方法名艾杏,參數(shù)類型韧衣,返回類型等等
  1. args對(duì)象數(shù)組,代表被調(diào)用方法的參數(shù)糜颠。注意基本類型(int,long)會(huì)被裝箱成對(duì)象類型(Interger, Long)

4. 執(zhí)行

        MyProxy myProxy = new MyProxy(new Car());
        
        BaseCar base = (BaseCar) Proxy.newProxyInstance
            (Object.class.getClassLoader(), new Class[]{BaseCar.class}, myProxy);
        
        base.run();

打印

汽車啟動(dòng)前
汽車啟動(dòng)
汽車啟動(dòng)后

動(dòng)態(tài)代理是Spring框架AOP的執(zhí)行原理,就是在需要執(zhí)行的方法執(zhí)行前后加入一些自定義的方法.

MyBatis的簡(jiǎn)單實(shí)現(xiàn)

先說說思路把,我們都知道MyBatis有一種使用方式,就是接口和xml配合使用,我最喜歡用這種方式因?yàn)閟ql語句和java代碼可以完全解耦,另外dao層的實(shí)現(xiàn)類都不用自己寫了,只需要在接口上面定義好方法,然后在對(duì)應(yīng)的xml文件中寫好與sql相關(guān)的配置就可以用了,MyBatis是我最喜歡用的一個(gè)框架(哎呀,跑題了),現(xiàn)在我們也要實(shí)現(xiàn)這樣的功能,不過相比MyBatis來說會(huì)簡(jiǎn)陋非常多,只為演示,所以各位不要吐槽.

1 . 首先我們定義好一個(gè)Dao接口,叫做TestDao :

public interface TestDao {
    Test selectTest();

然后再寫好對(duì)應(yīng)的xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cppteam.dao.TestDao">
  
  <select id="selectTest" resultType="com.cppteam.domain.Test">
    select * from test.test
  </select>
  
</mapper>

2 . 有一個(gè)名字為test的數(shù)據(jù)庫,名字為test的表

mysql> select * from test;

+----+------+
| id | name |
+----+------+
|  1 | 1    |
+----+------+
1 row in set (0.00 sec)

創(chuàng)建一個(gè)對(duì)應(yīng)的Test類

public class Test {

    private Integer id;

    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Test [id=" + id + ", name=" + name + "]";
    }

}

3 .創(chuàng)建一個(gè)代理類,代理TestDao類,對(duì)應(yīng)TestDao的每一個(gè)方法的執(zhí)行,都只獲取方法名,方法返回值等等,再利用獲取到的方法名去xml文件里面找,然后獲取對(duì)應(yīng)的sql語句,執(zhí)行sql語句之后,再通過反射獲取到返回值類型,再注入那個(gè)類對(duì)應(yīng)的實(shí)例,所以整個(gè)過程是不需要實(shí)現(xiàn)類的,我們現(xiàn)在開始.

sqlSession主要是配置連接數(shù)據(jù)庫,有一個(gè)select方法返回代理類

public class SqlSession {

    private static Connection connection = null;

    static {

        try {
            Class.forName("com.mysql.jdbc.Driver");

            connection = DriverManager.
                    getConnection("jdbc:mysql://localhost:3306/test?characterEncoding=utf-8", "root","123456");
        } catch (Exception e) {
            // TODO: handle exception
        }

    }

    public static Connection getConnection() {
        return connection;
    }

    public static <T> T select(Class<T> cls) {
        return (T) Proxy.newProxyInstance(cls.getClassLoader(), new Class[] { cls },
                new MyProxy());
    }

}

4 .這里看看MyProxy代理類(重點(diǎn)部分)

public class MyProxy implements InvocationHandler {

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // TODO Auto-generated method stub
        
        //先讀取xml文件
        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        
        Document xml = builder.parse(Object.class.getResourceAsStream("/com/cppteam/mapper/TestMapper.xml"));
        
        //找到第一個(gè)select結(jié)點(diǎn)
        Node node = xml.getElementsByTagName("select").item(0);
        
        NamedNodeMap attributes = node.getAttributes();
        
        //查找屬性id的值,對(duì)應(yīng)的應(yīng)該是接口中selectTest方法的名字
        Node id = attributes.getNamedItem("id");
        
        String methodName = method.getName();
        
        if(!id.getTextContent().trim().equals(methodName)){
            throw new Exception("找不到方法");
        }
        
        //找到對(duì)應(yīng)的sql語句
        String sql = node.getTextContent().trim();
        
        //開始執(zhí)行sql語句
        Connection connection = SqlSession.getConnection();
        
        connection.setAutoCommit(true);
        
        PreparedStatement prepareStatement = connection.prepareStatement(sql);
        
        ResultSet resultSet = prepareStatement.executeQuery();
        
        resultSet.next();
        
        //得到方法的返回值類型
        Class<?> returnType = method.getReturnType();
        
        System.out.println("方法名為:"+methodName+",方法返回值類型為:"+method.getReturnType().getName());
        
        System.out.println("執(zhí)行的sql為"+sql);
        
        Object newInstance = returnType.newInstance();
        
        Field[] declaredFields = newInstance.getClass().getDeclaredFields();
        
        //對(duì)返回值類型的實(shí)例進(jìn)行賦值
        for (Field field : declaredFields) {
            field.setAccessible(true);
            field.set(newInstance, resultSet.getObject(field.getName()));
        }
        return newInstance;
    }

}

5 .執(zhí)行

        TestDao testDao = SqlSession.select(TestDao.class);
        
        Test test = testDao.selectTest();
        
        System.out.println(test);

打印

方法名為:selectTest,方法返回值類型為:com.cppteam.domain.Test

執(zhí)行的sql為select * from test.test

Test [id=1, name=1]

我們應(yīng)該更加注重框架的原理,而不是框架的使用,從這個(gè)例子當(dāng)中,我們可以看到另一種應(yīng)用,就是不用實(shí)現(xiàn)類,直接通過動(dòng)態(tài)代理執(zhí)行接口方法,利用這個(gè)思路我們可以在別的方面做出更好的設(shè)計(jì).


另外說一下反射調(diào)用函數(shù),,假如現(xiàn)在有一個(gè)函數(shù):

public class Test {
    public void show(int num){
        System.out.println("函數(shù)參數(shù)為基本類型int");
    }
}

我們現(xiàn)在用反射對(duì)它進(jìn)行調(diào)用汹族,

public class Test1 {
    public static void show(Object object){
        Test.class.getMethod("show", object.getClass());
    }
    
    public static void main(String[] args) {
        int i = 1;
        show(1);
    }
}

運(yùn)行后萧求,報(bào)錯(cuò)了

 java.lang.NoSuchMethodException: com.cppteam.util.Test.show(java.lang.Integer)

Test1 的main函數(shù)中對(duì)本類中的show函數(shù)調(diào)用中其兴,參數(shù)為1,而show函數(shù)的參數(shù)用的是Object對(duì)象接收夸政,所以int類型的數(shù)值會(huì)被包裝為Integer類元旬,但是實(shí)際上存在的函數(shù)參數(shù)是int類型的,所以我們不得不加以判斷守问,然后轉(zhuǎn)型.

public class Test1 {
    public static void show(Object object) {
        
        Class<?> class1 = object.getClass();
        if (Integer.class.isInstance(object)) {
            class1 = int.class;
        }
        Method method = Test.class.getMethod("show", class1);
        
        method.invoke(new Test(), object);
    }

    public static void main(String[] args){
        int i = 1;
        show(i);
    }
}

運(yùn)行結(jié)果是成功的,看打釉裙椤:

函數(shù)參數(shù)為基本類型int
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市耗帕,隨后出現(xiàn)的幾起案子穆端,更是在濱河造成了極大的恐慌,老刑警劉巖仿便,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件体啰,死亡現(xiàn)場(chǎng)離奇詭異攒巍,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)荒勇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門柒莉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人沽翔,你說我怎么就攤上這事兢孝。” “怎么了仅偎?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵跨蟹,是天一觀的道長。 經(jīng)常有香客問我哨颂,道長喷市,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任威恼,我火速辦了婚禮品姓,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘箫措。我一直安慰自己腹备,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布斤蔓。 她就那樣靜靜地躺著植酥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪弦牡。 梳的紋絲不亂的頭發(fā)上友驮,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音驾锰,去河邊找鬼卸留。 笑死,一個(gè)胖子當(dāng)著我的面吹牛椭豫,可吹牛的內(nèi)容都是我干的耻瑟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼赏酥,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼喳整!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起裸扶,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤框都,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后呵晨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體魏保,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蔗蹋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了囱淋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片猪杭。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖妥衣,靈堂內(nèi)的尸體忽然破棺而出皂吮,到底是詐尸還是另有隱情,我是刑警寧澤税手,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布蜂筹,位于F島的核電站,受9級(jí)特大地震影響芦倒,放射性物質(zhì)發(fā)生泄漏艺挪。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一兵扬、第九天 我趴在偏房一處隱蔽的房頂上張望麻裳。 院中可真熱鬧,春花似錦器钟、人聲如沸津坑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疆瑰。三九已至,卻和暖如春昙啄,著一層夾襖步出監(jiān)牢的瞬間穆役,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國打工梳凛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留耿币,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓伶跷,卻偏偏與公主長得像掰读,于是被迫代替她去往敵國和親秘狞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子叭莫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,709評(píng)論 0 9
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理烁试,服務(wù)發(fā)現(xiàn)雇初,斷路器,智...
    卡卡羅2017閱讀 134,654評(píng)論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法减响,類相關(guān)的語法靖诗,內(nèi)部類的語法郭怪,繼承相關(guān)的語法,異常的語法刊橘,線程的語...
    子非魚_t_閱讀 31,630評(píng)論 18 399
  • 第一章:Java程序設(shè)計(jì)概述 Java和C++最大的不同在于Java采用的指針模型可以消除重寫內(nèi)存和損壞數(shù)據(jù)的可能...
    loneyzhou閱讀 1,251評(píng)論 1 7
  • 從荒野行動(dòng),終結(jié)者败晴,光榮使命浓冒,CF手游的荒島特訓(xùn)模式說一說吃雞游戲市場(chǎng)
    KEEP_PACE閱讀 300評(píng)論 0 0