1. 程式人生 > >Deep learning about Java--貫穿Java的反射機制(1)

Deep learning about Java--貫穿Java的反射機制(1)

筆者的mybatis文章暫且先更新到第5篇,因為要繼續深入理解mybatis的機制就不得不返回到我們的Java上,就是日後筆者繼續寫Hibernate的文章也是繞不過Java的反射機制。可以這麼說,筆者認為如果沒有了反射,Java就不會這麼強大!
進入這片文章的正題前,先介紹一個好東西lombok.jar,這是個神器(可以幫助我們偷懶的神器),減少我們新建類的時候寫一堆重複性的程式碼(這是JavaBean的要求)。

package com.unicorn.reflect.pojo;

import java.io.Serializable;

import lombok.EqualsAndHashCode;
import
lombok.Getter; import lombok.NoArgsConstructor; import lombok.NonNull; import lombok.Setter; import lombok.ToString; @NoArgsConstructor/**JavaBean規範:實現無參構造器*/ @ToString(exclude={"id"})/**JavaBean規範:過載tostring方法*/ @EqualsAndHashCode public class Emp implements Serializable, Person{/**JavaBean規範:類名的單詞首字母要大寫,其餘單詞的首字母也要大寫*/
/** * JavaBean規範:實現序列化介面 */ private static final long serialVersionUID = -720655243074260608L; /** * JavaBean規範:實現getter and setter * 在這裡使用lombok的註解簡化冗餘的程式碼 */ @Getter @Setter private Long id;/**JavaBean規範:屬性只有兩個字母的一律小寫,如:qq*/ @Getter @Setter private String empName;/**JavaBean規範:屬性的單詞首字母要小寫,其餘單詞的首字母也要大寫*/
@Getter @Setter private String depart; @Getter @Setter private Double salary; @Getter @Setter public Byte Sex; public static final int STABLE_VAL = 1; public Emp(@NonNull Long id){ this.id = id; } @Override public void testMethod() { // TODO Auto-generated method stub } @Override public void testMethod2() { // TODO Auto-generated method stub } @Override public int testMethod3(String str) { // TODO Auto-generated method stub return 0; } // @Override public boolean equals(Object o){ // if(o == this) // return true; // if(!(o instanceof Emp)) // return false; // } }

棒極了(主要是能偷懶了,不過筆者勸解:你要是在初學階段就老老實實地按著Javabean的規範幹活,寫吧!哈哈哈!)!筆者認為以後程式碼量是會一直以減少的趨勢發展的,簡潔的程式碼實現複雜的功能,筆者忍不住竊喜!估計日後程式語言的發展是真的會普及到大眾都能讀懂都能會寫,就像近代中國廢除文言文,舉國上下文、言一直都是白話文(當然世界的語言發展一直都是這樣的,中國不過是其中的一部分),擦亮眼睛看看到時那個程式設計界的哪天不高興了幹了和胡適(發表《文學改良芻議》)類似的事發一篇《程式設計改良芻議》!

要想輕鬆地使用lombok.jar就要先會安裝它,先下載lombok.jar(本來想上傳賺點積分的) : lombok.jar download url
筆者使用的RapidClipse(eclipse的加強版!!!其實就是配好環境和tools的eclipse),lombok的安裝居然是掃描不到RapidClipse的,這裡請允許筆者吐槽一下這有點智障!!!無奈,筆者只能手動安裝也是棒極了!

1.常規下的eclipse如何安裝:
開啟你的cmd(1. 通過小娜;2.ctrl+R:input cmd;自己安裝一個高大上的命令列,筆者推薦cmder)
輸入如下的命令(不要在意背景的女主!她好像是位歌手,筆者也想知道她叫什麼名字,知道的留個言唄!謝謝!):
這裡寫圖片描述
路徑要自己打!

java -jar ..\lombok.jar

這裡寫圖片描述
很明顯歧視筆者的RapidClipse!算了,見到上圖類似的情景後,點選install就可以安裝了!
裝好後,開啟eclipse所在目錄的eclipse.ini配置檔案,看看有沒有如下的兩段配置語句:
這裡寫圖片描述
這裡寫圖片描述
如果沒有的就自己添上去!

-javaagent:lombok.jar
-Xbootclasspath/a:lombok.jar

如上工作都完成後,就重啟eclipse並匯入lombok.jar的包到你的工程下:
project上右鍵->properties->Java BuildPath->Libaries->add external.jars(新增lombok.jar)
project上右鍵->properties->Java BuildPath->Libaries->add libaries(新增junit4)
這裡寫圖片描述
如上操作就可以使用了!

2.手動安裝

-javaagent:lombok.jar
-Xbootclasspath/a:lombok.jar

把上述的配置直接寫到eclipse.ini上,並把lombok.jar放到同一資料夾下即可(也可以放到plugins中)。
這裡寫圖片描述

3.進入reflect

public interface Person {
    public void testMethod();

    public void testMethod2();

    public int testMethod3(String str);
}
package com.unicorn.reflect.service;

import org.junit.Test;

import com.unicorn.reflect.pojo.Emp;

public class GetClassName {

    @Test
    public void getClazzName(){
        //way1:通過類本身來獲取,也就是this
                Class firstClass = this.getClass();
                System.out.println(firstClass.getName());
                System.out.println(firstClass.getSimpleName());

                //way2:通過類的例項化物件本身來獲取
                Emp e = new Emp();
                Class secondClass = e.getClass();
                System.out.println(secondClass.getName());
                System.out.println(secondClass.getSuperclass().getName());
                System.out.println(secondClass.getSimpleName());
                System.out.println(secondClass.getSuperclass().getSimpleName());

                //way3:通過類的全限定名獲取
                Class thirdClass = com.unicorn.reflect.pojo.Emp.class;
                System.out.println(thirdClass.getName());
                System.out.println(thirdClass.getSimpleName());

                //way4:通過類的許可權定名的字串獲取
                try {
                    Class fourthClass = Class.forName("com.unicorn.reflect.pojo.Emp");
                    System.out.println(fourthClass.getName());
                    System.out.println(fourthClass.getSimpleName());
                } catch (ClassNotFoundException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
    }

}
package com.unicorn.reflect.service;

import org.junit.Test;

import com.unicorn.reflect.pojo.Emp;

public class GetClassTest {

    /**
     * 獲取類物件的方式有4種
     */
    @SuppressWarnings("rawtypes")
    @Test
    public void getClassWays(){
        //way1:通過類本身來獲取,也就是this
        Class firstClass = this.getClass();
        System.out.println(firstClass);

        //way2:通過類的例項化物件本身來獲取
        Emp e = new Emp();
        Class secondClass = e.getClass();
        System.out.println(secondClass);
        System.out.println(secondClass.getSuperclass());

        //way3:通過類的全限定名獲取
        Class thirdClass = com.unicorn.reflect.pojo.Emp.class;
        System.out.println(thirdClass);

        //way4:通過類的許可權定名的字串獲取
        try {
            Class fourthClass = Class.forName("com.unicorn.reflect.pojo.Emp");
            System.out.println(fourthClass);
        } catch (ClassNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

    }

}
package com.unicorn.reflect.service;

import java.lang.reflect.Constructor;

import org.junit.Test;

/**
 * 獲取類中宣告的構造器
 * @author Unicorn
 *
 */
public class GetConstructor {

    @Test
    public void getConstructorTest(){
        try {
            Class clazz = Class.forName("com.unicorn.reflect.pojo.Emp");
            Constructor[] cs = clazz.getDeclaredConstructors();//這種方式能夠獲取所有已經宣告的構造器,不收到訪問許可權的限制

            for (Constructor constructor : cs) {
                System.out.println(constructor.getModifiers() + " "+ constructor.getName());
                Class[] temp = constructor.getParameterTypes();
                for (Class class1 : temp) {
                    System.out.println(class1.getName());
                }
            }

        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
package com.unicorn.reflect.service;

import java.lang.reflect.Field;

import org.junit.Test;

/**
 * 獲取類中成員屬性的資料型別,也成為域
 * @author Unicorn
 *
 */
public class GetField {

    @Test
    public void getFieldTest(){
        try {
            Class clazz = Class.forName("com.unicorn.reflect.pojo.Emp");
            Field[] fl = clazz.getFields();
            for (Field field : fl) {
                System.out.println(field.getName() + " " +field.getType().getName());//這裡由於許可權的問題,只能獲取訪問許可權為public的域
            }

            System.out.println("===============================");

            fl = clazz.getDeclaredFields();
            for (Field field : fl) {
                System.out.println(field.getName() + " " +field.getType().getName());//這裡可以獲取所有已經宣告的域
            }

        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
package com.unicorn.reflect.service;

import org.junit.Test;

/**
 * 類實現的interface
 * 在Java中類的繼承只能是單一的,也就是說,一個類只能繼承一個父類,然而,一個卻可以允許實現多個介面
 * @author Unicorn
 *
 */
public class GetInterface {

    @Test
    public void getInterfaceTest(){
        try {
            Class _class = Class.forName("com.unicorn.reflect.pojo.Emp");
            Class[] its = _class.getInterfaces();
            int i = 0;
            for (Class c : its) {
                System.out.println(++i + " the inteface is: " + c.getName());//打印出實現了的所有介面的全限定名
            }

        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}
package com.unicorn.reflect.service;

import java.lang.reflect.Method;

import org.junit.Test;

/**
 * 獲取類中宣告的所有方法
 * @author Unicorn
 *
 */
public class GetMethod {

    @Test
    public void getMethodTest(){
        try {
            Class clazz = Class.forName("com.unicorn.reflect.pojo.Emp");
            Method[] m = clazz.getDeclaredMethods();//這裡也是不受訪問許可權限制的
            for (Method method : m) {
                System.out.println(method.getReturnType() + "" + method.getName());
                Class[] param = method.getParameterTypes();
                for (Class class1 : param) {
                    System.out.println(class1.getName());
                }
                Class[] ex = method.getExceptionTypes();
                for (Class class1 : ex) {
                    System.out.println(class1.getName());
                }
                System.out.println("================================");
            }

        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
package com.unicorn.reflect.service;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import org.junit.Test;

/**
 * Modifier變數域的檢索
 * @author Unicorn
 *
 */
public class GetModifier {

    @SuppressWarnings("rawtypes")
    @Test
    public void getModifierTest() throws ClassNotFoundException{
        Class _class = Class.forName("com.unicorn.reflect.pojo.Emp");
        int num = _class.getModifiers();
        System.out.println("the number of Modifier:" + num);

        Field[] fl = _class.getDeclaredFields();
        int i = 0;
        for (Field field : fl) {
            System.out.println(++i + " this modifier is: " + Modifier.toString(field.getModifiers()));
        }
    }

}

反射的第一階段就這樣先了!
轉載請註明出處,謝謝!