本篇重點講解java基礎知識與系統提供api的運用
java class類
java中某個類無論生成多少個對象,這些對象都會對應同一個Class對象,這個Class對象由JVM生成,通過它可以獲悉整個類的結構,包括方法、屬性等等。
原理
所有的java類都是繼承Object,在object類中有一個getClass方法,這個方法是用來取得該類已經被實例化的對象的引用,這個引用指向的class類的對象,我們自己無法生成一個class對象(構造函數爲private),這個class類的對象在各類被調用時,有JVM虛擬機自動創建Class對象,或通過各類裝載器中的defineClass方法生成,
Class方法:
Class.forName("java.lang.string");、Class class = 類.class;、Class class = 對象.class
以上三種方式都可獲得class對象,三種方法得到的結果也是一樣的
在運行期間,如果我們要產生某個類的對象,java虛擬機(JVM)會檢查該類型的class對象是否已被加載,如果沒有被加載,JVM會根據類的名字找到.class對象並加載它,一旦某個類的對象被加載到內存中,就可以用來產生所有類的對象,虛擬機只會產生一份字節碼,用這份字節碼可以產生多個實例對象。
Class.isPrimitive()
Class.isPrimitive():判斷指定Class對象是否表示一個java基本數據類型;boolean、char、int、short、long、float、double、byte;返回boolean類型,true表示是基本數據類型,false表示不是基本數據類型
Class.forName()
Class.forName():要求JVM查找並加載指定類,作用是加載指定靜態模塊,加載了之後進行初始化操作才能正常使用該類,類的初始化操作就是執行一遍靜態語句,包括靜態變量的聲明和靜態代碼塊
使用Class.forName( )靜態方法的目的是爲了動態加載類。在加載完成後,一般還要調用Class下的newInstance( )靜態方法來實例化對象以便操作。因此,單單使用Class.forName( )是動態加載類是沒有用的,其最終目的是爲了實例化對象。
Class.forName()的作用是要求JVM查找並加載指定的類,首先要明白,java裏面任何class都要裝載在虛擬機上才能運行,而靜態代碼是和class綁定的,class裝載成功就表示執行了你的靜態代碼了,而且以後不會再走這段靜態代碼了。
Class.getField、Class.getDeclaredField返回成員變量
Class.getField()返回已加載類聲明的所有public成員變量的Field對象,包括從父類繼承過來的成員變量,參數name指定成員變量的名稱。
Class.getDeclaredField()返回當前類所有成員變量。
如果想要獲取父類的所有成員變量(主要是爲了拿到私有成員變量,只想獲取公有成員變量可以直接使用getField),可以通過取得當前類的父類的class對象再調用getDeclaredField方法。
Class.getMethod、Class.getDeclaredMethods返回method對象
Class.getMethod():獲取當前類以及所有集成的父類的public修飾的方法,僅包含public
Class.getDeclaredMethods:獲取當前類的所有方法,包括public/private/protected/default
java反射湖獲取某個類的全部屬性
1. forName() 返回給定串名相應的Class對象。
2. getDeclaredFields() 返回當前Class對象表示的類或接口的所有已說明的域對象數組。
3. getFields() 返回當前Class對象表示的類或接口的所有可訪問的公有域對象數組。
4. getModifiers() 返回該類或接口的Java語言修改器代碼。
5. getName() 返回Class對象表示的類型(類、接口、數組或基類型)的完整路徑名字符串。
要反射的類
package com.my.javahookdemo.test;
public class Father {
public String name;
public String sex;
private String adds;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAdds() {
return adds;
}
public void setAdds(String adds) {
this.adds = adds;
}
}
反射方法:
Class<?> clazz = null;
try {
clazz = Class.forName("com.my.javahookdemo.test.Father");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("===============本類屬性===============");
// 取得本類的全部屬性
Field[] field = clazz.getDeclaredFields();
for (int i = 0; i < field.length; i++) {
// 權限修飾符
int mo = field[i].getModifiers();
String priv = Modifier.toString(mo);
// 屬性類型
Class<?> type = field[i].getType();
System.out.println(priv + "---01--->>>" + type.getName() + " " + field[i].getName() + ";");
}
System.out.println("==========實現的接口或者父類的屬性==========");
// 取得實現的接口或者父類的屬性
Field[] filed1 = clazz.getFields();
for (int j = 0; j < filed1.length; j++) {
// 權限修飾符
int mo = filed1[j].getModifiers();
String priv = Modifier.toString(mo);
// 屬性類型
Class<?> type = filed1[j].getType();
System.out.println(priv + "---02--->>>" + type.getName() + " " + filed1[j].getName() + ";");
}
打印log:
12-26 17:12:45.691 26675-26675/com.my.javahookdemo I/System.out: ===============本類屬性===============
12-26 17:12:45.692 26675-26675/com.my.javahookdemo I/System.out: private---01--->>>java.lang.String adds;
12-26 17:12:45.692 26675-26675/com.my.javahookdemo I/System.out: public---01--->>>java.lang.String name;
12-26 17:12:45.693 26675-26675/com.my.javahookdemo I/System.out: public---01--->>>java.lang.String sex;
12-26 17:12:45.693 26675-26675/com.my.javahookdemo I/System.out: ==========實現的接口或者父類的屬性==========
12-26 17:12:45.693 26675-26675/com.my.javahookdemo I/System.out: public---02--->>>java.lang.String name;
12-26 17:12:45.693 26675-26675/com.my.javahookdemo I/System.out: public---02--->>>java.lang.String sex;
可以看到屬性按照意向的已經打印出來了
java通過反射實例化一個類對象
1. forName() 返回給定串名相應的Class對象。
2. newInstance() 創建類的新實例。
3. getConstructors() 返回當前Class對象表示的類的所有公有構造子對象數組。
4. getName() 返回Class對象表示的類型(類、接口、數組或基類型)的完整路徑名字符串。
user類
package com.my.javahookdemo.test;
public class User {
private int age;
private String name;
public User() {
super();
}
public User(String name) {
super();
this.name = name;
}
public User(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User [age=" + age + ", name=" + name + "]";
}
}
Class<?> class1 = null;
try {
class1 = Class.forName("com.my.javahookdemo.test.User");
// 第一種方法,實例化默認構造方法,調用set賦值
User user = (User) class1.newInstance();
user.setAge(20);
user.setName("Rollen");
System.out.println(user);
// 結果 User [age=20, name=Rollen]
// 第二種方法 取得全部的構造函數 使用構造函數賦值
Constructor<?> cons[] = class1.getConstructors();
// 查看每個構造方法需要的參數
for (int i = 0; i < cons.length; i++) {
Class<?> clazzs[] = cons[i].getParameterTypes();
System.out.print("--0->cons[" + i + "] (");
for (int j = 0; j < clazzs.length; j++) {
if (j == clazzs.length - 1) {
System.out.print("--1->"+clazzs[j].getName());
} else {
System.out.print("--2->"+clazzs[j].getName() + ",");
}
}
System.out.println("--3->)");
}
} catch (Exception e) {
e.printStackTrace();
}
打印結果
12-26 17:30:06.241 29267-29267/com.my.javahookdemo I/System.out: User [age=20, name=Rollen]
12-26 17:30:06.242 29267-29267/com.my.javahookdemo I/System.out: --0->cons[0] (--3->)
12-26 17:30:06.242 29267-29267/com.my.javahookdemo I/System.out: --0->cons[1] (--2->int,--1->java.lang.String--3->)
12-26 17:30:06.243 29267-29267/com.my.javahookdemo I/System.out: --0->cons[2] (--1->java.lang.String--3->)
java通過反射機制獲取某個類的全部方法
1. forName() 返回給定串名相應的Class對象。
2. getMethods() 返回當前Class對象表示的類或接口的所有公有成員方法對象數組,包括已聲明的和從父類繼承的方法。
3. getModifiers() 返回該類或接口的Java語言修改器代碼。
4. getName() 返回Class對象表示的類型(類、接口、數組或基類型)的完整路徑名字符串。
package com.my.javahookdemo.test;
public class Father {
public String name;
public String sex;
private String adds;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAdds() {
return adds;
}
public void setAdds(String adds) {
this.adds = adds;
}
private void test(){
}
public void testmethod(String name){
}
public void helloMethod(){
}
}
Class<?> clazz = null;
try {
clazz = Class.forName("com.my.javahookdemo.test.Father");
Method method[] = clazz.getMethods();
for (int i = 0; i < method.length; ++i) {
Class<?> returnType = method[i].getReturnType();
Class<?> para[] = method[i].getParameterTypes();
int temp = method[i].getModifiers();
System.out.print(Modifier.toString(temp) + "--01-->>");
System.out.print(returnType.getName() + "--02-->>");
System.out.print(method[i].getName() + "--03-->>");
System.out.print("(");
for (int j = 0; j < para.length; ++j) {
System.out.print(para[j].getName() + " " + "arg" + j);
if (j < para.length - 1) {
System.out.print("--04-->>");
}
}
Class<?> exce[] = method[i].getExceptionTypes();
if (exce.length > 0) {
System.out.print(") throws ");
for (int k = 0; k < exce.length; ++k) {
System.out.print(exce[k].getName() + "--05-->>");
if (k < exce.length - 1) {
System.out.print("--06s-->>");
}
}
} else {
System.out.print(")");
}
System.out.println();
}
} catch (Exception e) {
e.printStackTrace();
}
打印log
System.out: public--01-->>boolean--02-->>equals--03-->>(java.lang.Object arg0)
System.out: public--01-->>java.lang.String--02-->>getAdds--03-->>()
System.out: public final--01-->>java.lang.Class--02-->>getClass--03-->>()
System.out: public--01-->>java.lang.String--02-->>getName--03-->>()
System.out: public--01-->>java.lang.String--02-->>getSex--03-->>()
System.out: public--01-->>int--02-->>hashCode--03-->>()
System.out: public--01-->>void--02-->>helloMethod--03-->>()
System.out: public final native--01-->>void--02-->>notify--03-->>()
System.out: public final native--01-->>void--02-->>notifyAll--03-->>()
System.out: public--01-->>void--02-->>setAdds--03-->>(java.lang.String arg0)
System.out: public--01-->>void--02-->>setName--03-->>(java.lang.String arg0)
System.out: public--01-->>void--02-->>setSex--03-->>(java.lang.String arg0)
System.out: public--01-->>void--02-->>testmethod--03-->>(java.lang.String arg0)
System.out: public--01-->>java.lang.String--02-->>toString--03-->>()
System.out: public final native--01-->>void--02-->>wait--03-->>() throws java.lang.InterruptedException--05-->>
System.out: public final--01-->>void--02-->>wait--03-->>(long arg0) throws java.lang.InterruptedException--05-->>
System.out: public final native--01-->>void--02-->>wait--03-->>(long arg0--04-->>int arg1) throws java.lang.InterruptedException--05-->>