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()));
}
}
}
反射的第一階段就這樣先了!
轉載請註明出處,謝謝!