【笔记】Java的反射

前言

Java的反射学习笔记

获取类对象

通过类名获取类对象

1
2
3
class Cls {}

Class<Cls> clazz = Cls.class;

通过类的全局限定名获取类对象

1
2
3
class Cls {}

Class<?> clazz = Class.forName("com.example.Cls");

通过对象获取类对象

1
2
3
4
class Cls {}
Cls cls = new Cls();

Class<? extends Cls> clazz = cls.getClass();

基本类型获取类对象

1
2
3
4
Class<Integer> clazz1 = int.class;
Class<Integer> clazz2 = Integer.TYPE;

System.out.println(clazz1 == clazz2); // true
  • 基本类型的类对象和包装类的类对象不是相同的
1
2
3
4
Class<Integer> clazz1 = int.class;
Class<Integer> clazz2 = Integer.class;

System.out.println(clazz1 == clazz2); // false

获取viod类对象

1
Class<Void> clazz = void.class;
  • Void值只有null
1
Void v = null;

获取数组类对象

1
Class<int[]> clazz = int[].class;

多维数组

1
Class<int[][]> clazz = int[][].class;

类对象的实例方法

获取类对象名

获取类对象名

  • 除了数组类对象,其他类对象都返回类的全局限定名
1
String name = clazz.getName();

获取类对象简单名

  • 返回类名
1
String simpleName = clazz.getSimpleName();

获取类对象类型名

  • 返回类的全局限定名
1
String typeName = clazz.getTypeName();

类对象转换为实例对象

1
2
3
4
5
6
7
class Cls {}
Class<Cls> clazz = Cls.class;
Cls cls1 = new Cls();

Cls cls2 = clazz.cast(cls1);

System.out.println(cls1 == cls2); // true

获取子类类对象

1
Class<? extends Cls> subclass = clazz.asSubclass(Cls.class);

获取父类类对象

1
Class<? super Cls> superclass = clazz.getSuperclass();

包含泛型参数

1
Type genericSuperclass = clazz.getGenericSuperclass();

获取接口类对象数组

1
Class<?>[] interfaces = clazz.getInterfaces();

包含泛型参数

1
Type[] genericInterfaces = clazz.getGenericInterfaces();

通过类对象获取包对象

1
Package package = clazz.getPackage();

包对象的实例方法

获取包名

1
String name = package.getName();

直接通过类对象创建对象

  • 直接通过类对象创建对象时,只能使用类定义的无参构造器,如果无参构造器不存在则会报错
1
2
3
4
5
class Cls {
public Cls() {}
}

Cls cls = clazz.newInstance();

通过类对象获取构造器对象

通过构造器对象创建对象

无参构造

1
2
3
4
5
6
class Cls {
public Cls() {}
}

Constructor<Cls> constructor = clazz.getConstructor();
Cls cls = constructor.newInstance();
  • 强制使用私有构造器对象创建对象
    • 通过setAccessible()方法设置权限
1
2
3
4
5
6
7
class Cls {
private Cls() {}
}

Constructor<Cls> constructor = clazz.getDeclaredConstructor();
constructor.setAccessible(true);
Cls cls = constructor.newInstance();

有参构造

  • 在调用getConstructor()方法时指定形参类型
1
2
3
4
5
6
class Cls {
public Cls(String str) {}
}

Constructor<Cls> constructor = clazz.getConstructor(String.class);
Cls cls = constructor.newInstance();
  • 强制使用私有构造器对象创建对象
    • 通过setAccessible()方法设置权限
1
2
3
4
5
6
7
class Cls {
private Cls(String str) {}
}

Constructor<Cls> constructor = clazz.getDeclaredConstructor(String.class);
constructor.setAccessible(true);
Cls cls = constructor.newInstance();

构造器对象的实例方法

获取构造器名

1
String name = constructor.getName();

通过类对象获取方法对象

通过方法对象执行方法

无参方法

1
2
3
4
5
6
7
class Cls {
public void method() {}
}
Cls cls = new Cls();

Method method = clazz.getMethod("method");
method.invoke(cls);
  • 强制使用私有方法对象执行方法
    • 通过setAccessible()方法设置权限
1
2
3
4
5
6
7
8
class Cls {
private void method() {}
}
Cls cls = new Cls();

Method method = clazz.getDeclaredMethod("method");
method.setAccessible(true);
method.invoke(cls);

有参方法

  • 在调用getMethod()方法时指定形参类型
1
2
3
4
5
6
7
class Cls {
public void method(String str) {}
}
Cls cls = new Cls();

Method method = clazz.getMethod("method", String.class);
method.invoke(cls, "");
  • 强制使用私有方法对象执行方法
    • 通过setAccessible()方法设置权限
1
2
3
4
5
6
7
8
class Cls {
private void method(String str) {}
}
Cls cls = new Cls();

Method method = clazz.getDeclaredMethod("method", String.class);
method.setAccessible(true);
method.invoke(cls, "");
具有可变参数作为形参的方法
  • 通过数组匹配可变参数
1
2
3
4
5
6
7
class Cls {
public void method(String... str) {}
}
Cls cls = new Cls();

Method method = clazz.getMethod("method", String[].class);
method.invoke(cls, Arrays.asList(""));

方法对象的实例方法

获取方法名

1
String name = method.getName();

获取方法的返回值类型

1
Class<?> returnType = method.getReturnType();

获得成员变量的定义信息

得到可见的所有成员变量

  • 包括继承的变量
1
getFields()

获得包括不可见的所有变量

  • 包括私有变量,不包括继承的变量
1
getDeclaredFields()

获得可见的一个变量

<name>:变量名

1
getField(<name>)

获得包括不可见的一个变量

1
getDeclaredField(<name>)

获得构造方法的定义信息

获得可见的构造方法

1
getConstructors()

获得包括不可见的构造方法

1
getDeclaredConstructors()

获得可见的一个构造方法

<int>.class:基本类型的类对象

1
getConstructor(<int>.class)

获得包括不可见的一个构造方法

1
getDeclaredConstructor(<int>.class)

获得方法的定义信息

获得可见的方法

  • 包括继承的方法
1
getMethods()

获得本类定义的方法

  • 包括私有方法,不包括继承的方法
1
getDeclearedMethods()

获得可见的一个方法

<method>:方法名

1
getMethod(<method>, <int>.class)

获得本类定义的一个方法

1
getDeclearedMethod(<method>, <int>.class)

创建对象

利用无参构造创建

1
newInstance()

利用有参构造创建

<str>:以字符串为例利用有参构造创建对象

1
2
c.getConstaructor(String.class);
c.newInstance("<str>");

执行方法

1
invoke()

暴力反射

暴力反射关键字

  • Decleared

设置权限

  • 访问私有属性时,需要先设置访问权限,才可以访问
1
c.setAccessible(true);

完成