欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java反射学习

程序员文章站 2024-01-20 22:31:52
...

Java反射学习

标签(空格分隔): Java


反射定义

反射通常被用来检测和修改运行在Java虚拟机的应用程序的行为。这是一个相对高级的特性,只应该由语言基础很强的开发人员使用。值得说明的是,反射是一种强大的技术特性,可以使应用程序执行一些非常规的操作。

反射入口

  1. 通过Object.getClass(),即对象的实例来获取
public class Car {}

public class Test {

    public static void main(String[] args) {

        Car car = new Car();
        Class clazz = car.getClass();
    }
}
  1. 通过.class标识,类来获取
public class Test {
    public static void main(String[] args) {

        Class clazz = Car.class;
        Class cls1 = int.class;
        Class cls2 = String.class;
    }
}
  1. 通过Class.forName获取
    有一些类并不存在与开发环境,只能通过包名.类名来获取
try {
    Class clz = Class.forName("com.frank.test.Car");
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

Class对象内容

  1. Class名字
/**
 * Class为引用时返回二进制形式的字符串,比如“com.example.test.Car”
 * Class为基本数据类型,比如int.class,返回关键字int
 * Class为基础类型的数组,如int[][][],返回[[[I
 */
Class.getName();
/**
 * 去包名限定,如果是数组类型,在后面添加[],比如I[][][]
 * 匿名内部类返回空字符串
 */
Class.getSimpleName();
/**
 * 官方名,返回包名+simpleName,局部类和匿名内部类返回null
 */
Class.getCanonicalName();
元素类型 编码
boolean Z
byte B
char C
double D
float F
int I
long J
short S
类或接口 L类名;
  1. Class修饰符
/**
 * 返回的是整数
 */
Class.getModifiers() ;
/**
 * 返回的是字符串
 */
Modifier.toString(Class.getModifiers());
  1. 获取Filed
/**
 * 获取私有属性
 */
public Field getDeclaredField(String name)
                       throws NoSuchFieldException,
                              SecurityException;
/**
 * 获取非私有属性,获取不到会向祖先类获取
 */
public Field getField(String name)
               throws NoSuchFieldException,
                      SecurityException;
                
/**
 * 获取所有的属性,但不包括从父类继承下来的属性
 */
public Field[] getDeclaredFields() throws SecurityException {}

/**
 * 获取自身的所有的 public 属性,包括从父类继承下来的。
 */
public Field[] getFields() throws SecurityException {
  1. 获取Method

public Method getDeclaredMethod(String name, Class<?>... parameterTypes)

public Method getMethod(String name, Class<?>... parameterTypes)

public Method[] getDeclaredMethods() throws SecurityException

public Method getMethod(String name, Class<?>... parameterTypes) 
/**
 * 获取构造方法
 */
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)

public Constructor<T> getConstructor(Class<?>... parameterTypes)

public Constructor<?>[] getDeclaredConstructors() throws SecurityException 

public Constructor<?>[] getConstructors() throws SecurityException

Field操控

  1. 获取Field类型和修饰符类型
/**
 * 能够获取到泛型,更详细  
 */
public Type getGenericType() {}

public Class<?> getType() {}

/**
 * 能够获取修饰符 
 */
 public int getModifiers() {}
  1. Field内容读取和赋值
    有一系列setXXX(Object object, xxx value)getXXX(Object object)函数可以调用
    Object是指定要读哪个实例
    另外如果访问private修饰的成员,会抛异常,要访问修改权限即可
field.setAccessible(true);

Method操控

  1. 获取内容
/**
 * 获取方法名
 */
method.getName();
/**
 * 获取方法参数等等。。。
 */
method.getParameters();
  1. 执行方法
/**
 * 第一个参数是对象实例,如果是静态方法填null
 * 第二个动态参数是方法的参数列表
 * 返回的对象是Object,实际执行要进行强制转换
 */
public Object invoke(Object obj, Object... args) {}

Constructor操控

两种方法创建对象实例,推荐使用后面一种

Class.newInstance();
Constructor.newInstance()

反射中的数组

  1. 获取类型
    Class里有一个方法判断是不是数组类型
public native boolean isArray();

可以通过getName()getComponentType()获取数组类型和数组里的元素类型

  1. 动态创建数组
    通过Array.newInstance()方法,第一个参数数组元素类型,后面动态参数是维度大小
public static Object newInstance(Class<?> componentType, int... dimensions)
        throws IllegalArgumentException, NegativeArraySizeException {}
  1. 读取和赋值
public void set(Object obj,
                Object value)
         throws IllegalArgumentException,
                IllegalAccessException;


public Object get(Object obj)
           throws IllegalArgumentException,
                  IllegalAccessException;

反射中的枚举

操控枚举,枚举的获取和设定和Fieled一样

// 用来判定 Class 对象是不是枚举类型
Class.isEnum()

// 获取所有的枚举常量
Class.getEnumConstants()

// 判断一个 Field 是不是枚举常量
java.lang.reflect.Field.isEnumConstant()

细说反射,Java 和 Android开发者必须跨越的坎