本篇重点讲解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-->>