java 反射基础知识与实践

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

 

 

发布了15 篇原创文章 · 获赞 0 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qinggancha/article/details/103709290