获取到Class对象之后,就可以利用Class对象获取和操作类的属性、构造器、方法、父类和接口了。

所有的方法都可以查java.lang.Class的api文档。

以下逐一介绍:

1.属性

通过Class对象获取类的属性:

//获取所有公共的属性
Field[] getFields();
//获取所有的属性(包含四种修饰符修饰的)
Field[] getDeclaredFields();
//获取指定的某一个公有属性
Field getField("属性名字");
//获取指定的某一个属性(包含四种修饰符修饰的)
Field getDeclaredField("属性名字")

获取到Field对象或者数组之后,Field类也有以下常用方法:

//获取属性名
String getName();
//给属性赋值
void set(Object obj, Object value);
//获取属性的值
Object get(Object obj);	//如果想获取私有的,就要打破封装setAccessible(true);--->缺点:不安全
//获取属性的数据类型
Class<?> getType();
//获取类的修饰符
int getModifiers();

获取类的修饰符的返回值为int,要通过Modifier类将int类型转换为对应的修饰符:

Modifier.toString(参数为getModifiers()的返回值);

综合例子:

User类:具有四个修饰权限的属性

package com.dh.field;

public class User {
    public String name;
    int age;
    protected int no;
    private char sex;
}

测试类:

package com.dh.field;

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

public class ReflectField {
    public static void main(String[] args) {
        //获取类名
        ResourceBundle bundle = ResourceBundle.getBundle("className");
        String name = bundle.getString("className");
//        System.out.println(name);
        Class c = null;
        try {
            //获取Class
            c = Class.forName(name);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //获取类的简单名称
        String simpleName = c.getSimpleName();
        //获取类的所有公共属性
        System.out.println("------------"+simpleName+"类的所有公共属性:");
        Field[] fields = c.getFields();
        for (Field field : fields) {
            //获取属性的名称
            System.out.println(field.getName());
        }
        //获取类的所有属性
        System.out.println("------------"+simpleName+"类的所有属性:");
        Field[] fields1 = c.getDeclaredFields();
        for (Field field : fields1) {
            //获取属性的修饰符、数据类型、名称
            System.out.println(Modifier.toString(field.getModifiers())
                    +"\t" +field.getType().getSimpleName()
                    +"\t"+field.getName());
        }
        //获取指定的公共属性
        System.out.println("------------公共的属性为:");
        try {
            Field name1 = c.getField("name");
            System.out.println(name1.getName());
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        //获取指定的属性(四种权限)
        Field sex = null;
        //创建一个对象
        Object o = null;
        try {
            o = c.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        try {
            sex = c.getDeclaredField("sex");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        try {
            //给私有属性赋值需要先打破封装
            sex.setAccessible(true);
            sex.set(o,'女');
            System.out.println("------------给"+sex.getName()+"添加属性成功!");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        //获取属性值
        try {
            Object o1 = sex.get(o);
            System.out.println("------------"+sex.getName()+"的属性值为:");
            System.out.println(o1);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

结果:

------------User类的所有公共属性:
name
------------User类的所有属性:
public static	String	name
	int	age
protected	int	no
private	char	sex
------------公共的属性为:
name
------------给sex添加属性成功!
------------sex的属性值为:
女

2.构造方法

通过Class对象获取类的构造方法:

//获取所有公共的构造方法
Constructor<T>[] getConstructors();
//获取所有的构造方法(包含四种修饰符修饰的)
Constructor<T>[] getDeclaredConstructors();
//获取指定的某一个构造方法
Constructor<T> getConstructor(类<?>... parameterTypes); 
//获取指定的某一个构造方法(包含四种修饰符修饰的)
Constructor<T> getDeclaredConstructor(类<?>... parameterTypes);
//获取数据类型
String getTypeName();

获取到Constructor对象或者数组之后,Constructor类也有以下常用方法:

//获取构造方法的修饰符
int getModifiers();
//获取构造方法的参数
Class<>[] getParameterTypes();
//创建对象
T newInstance(Object... initargs); //如果想利用私有的构造方法,就要打破封装setAccessible(true);--->缺点:不安全

获取类的修饰符的返回值为int,要通过Modifier类将int类型转换为对应的修饰符:

Modifier.toString(参数为getModifiers()的返回值);

综合例子:

User类:

package com.dh.constructor;

public class User {
    public static String name;
    int age;
    protected int no;
    private char sex;

    public User() {
    }

    public User(int age) {
        this.age = age;
    }

    private User(int age, int no, char sex) {
        this.age = age;
        this.no = no;
        this.sex = sex;
    }
}

测试类:

package com.dh.constructor;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.util.ResourceBundle;

public class ReflectConstructor {
    //为了代码好看些,将所有的异常都采取throws的方式
    public static void main(String[] args) throws Exception {
        
        //获取类名
        ResourceBundle bundle = ResourceBundle.getBundle("className");
        String name = bundle.getString("className2");
        
        //获取Class对象
        Class c = Class.forName(name);
        
        //获取公共的构造器
        Constructor[] constructors = c.getConstructors();
        for (Constructor constructor : constructors) {
            
            //获取构造器中的修饰符
            System.out.print(Modifier.toString(constructor.getModifiers()));
            System.out.print("\t");
            
            //获取构造方法名
            System.out.print(c.getSimpleName());
            
            //获取构造方法参数
            Class[] parameterTypes = constructor.getParameterTypes();
            for (Class parameterType : parameterTypes) {
                //获取参数的类型
                System.out.print("\t");
                System.out.print(parameterType.getTypeName());
            }
            System.out.println();
        }
        //获取所有的构造器
        Constructor[] declaredConstructors = c.getDeclaredConstructors();
        System.out.println(declaredConstructors.length);
        
        //获取指定的公共构造器
        Constructor constructor = c.getConstructor(int.class);
        
        //通过指定的构造器创建对象
        //Constructor类newInstance()的没有过时!!!
        Object o = constructor.newInstance(1);
        System.out.println(o);
        
        //获取指定的私有的构造器
        Constructor declaredConstructor = c.getDeclaredConstructor(int.class, int.class,char.class);
        
        //开放私有构造方法权限
        declaredConstructor.setAccessible(true);
        Object o1 = declaredConstructor.newInstance(1, 1,'女');
        System.out.println(o1);
    }
}

结果:

public	User
public	User	int
3
com.dh.constructor.User@13fee20c
com.dh.constructor.User@4e04a765

3.方法

通过Class对象获取类的方法:

//获取所有公共的方法
Method[] getMethods();
//获取所有的方法(包含四种修饰符修饰的)
Method[] getDeclaredMethods();
//获取指定的某一个方法
Method getMethod(String name,类<?>... parameterTypes); 
//获取指定的某一个方法(包含四种修饰符修饰的)
Method getMethod(String name,类<?>... parameterTypes);
//获取数据类型
String getTypeName();

获取到Method对象或者数组之后,Method类也有以下常用方法:

//获取构造方法的修饰符
int getModifiers();
//获取方法的返回值类型
Class getReturnType();
//获取方法名
String getName();
//获取方法的参数
Class<>[] getParameterTypes();
//执行方法
Object invoke(Object obj, Object... args);//如果执行私有的方法,就要打破封装setAccessible(true);--->缺点:不安全

获取类的修饰符的返回值为int,要通过Modifier类将int类型转换为对应的修饰符:

Modifier.toString(参数为getModifiers()的返回值);

综合例子:

User:

package com.dh.method;

public class User {

    public void sayHi() {
        System.out.println("hello");
    }

    protected static String Print(String s) {
        return s;
    }

    private int add(int a, int b) {
        return a + b;
    }
}

测试:

package com.dh.method;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.TypeVariable;
import java.util.ResourceBundle;

public class ReflectMethod {
    public static void main(String[] args) throws Exception {
        //获取类名
        ResourceBundle bundle = ResourceBundle.getBundle("className");
        String name = bundle.getString("className3");
        //获取Class对象
        Class c = Class.forName(name);
        //获取公有的方法(包含九个Object类的)
        Method[] methods = c.getMethods();
        for (Method method : methods) {
            System.out.print(method.getName()+"\t");
        }
        System.out.println();
        //获取所有的方法
        Method[] declaredMethods = c.getDeclaredMethods();
        for (Method method : declaredMethods) {
            //获取方法的修饰符
            System.out.print(Modifier.toString(method.getModifiers())+"\t");
            //获取方法的返回值
            System.out.print(method.getReturnType().getSimpleName()+"\t");
            //获取方法名
            System.out.print(method.getName()+"\t");
            //获取方法的参数
            Class[] parameterTypes = method.getParameterTypes();
            for (Class type : parameterTypes) {
                System.out.print(type.getSimpleName()+"\t");
            }
            System.out.println();
        }
        //获取某个指定的公共方法
        Method sayHi = c.getDeclaredMethod("sayHi");
        System.out.println(sayHi);
        //获取某个指定的私有方法
        Method add = c.getDeclaredMethod("add", int.class, int.class);
        //调用某个方法
        //参数需要对象和实参
        Object o = c.getConstructor().newInstance();
        //调用私有方法需要先设置权限
        add.setAccessible(true);
        Object result = add.invoke(o, 1, 1);
        System.out.println(result);
    }
}

结果:

sayHi	wait	wait	wait	equals	toString	hashCode	getClass	notify	notifyAll	
private	int	add	int	int	
public	void	sayHi	
protected static	String	Print	String	
public void com.dh.method.User.sayHi()
2

4.父类和接口

一个类的父类只有一个。通过Class对象获取:

类<? super T> getSuperClass();

但是可以实现多个接口:

类<?>[] getInterfaces();

**再使用getName()获得类和接口的名称(完整的)。


虽然方法很多,但是都有异曲同工之妙,并且很多都能够自己猜测到方法的名称。