java.lang.Class类
java.lang.Class主要提供了以下两个功能:
- 提供方法用于访问运行期间类的元数据;
- 提供方法用于检查和修改类的运行时行为;
java.lang.Class类常用方法
Method | Description |
---|---|
1) public String getName() | 返回类名 |
2) public static Class forName(String className)throws ClassNotFoundException | 加载类并返回Class对象 |
3) public Object newInstance()throws InstantiationException,IllegalAccessException | 创建实例对象 |
4) public boolean isInterface() | 判断是否是接口 |
5) public boolean isArray() | 判断是否是数组 |
6) public boolean isPrimitive() | 判断是否是原始数据类型 |
7) public Class getSuperclass() | 返回父类Class引用 |
8) public Field[] getDeclaredFields()throws SecurityException | 返回类的成员属性字段数组 |
9) public Method[] getDeclaredMethods()throws SecurityException | 返回类的方法数组 |
10) public Constructor[] getDeclaredConstructors()throws SecurityException | 返回类的构造方法数组 |
11) public Method getDeclaredMethod(String name,Class[] parameterTypes)throws NoSuchMethodException,SecurityException | 返回类中指定参数类型的方法 |
获取Class对象的三种方式
有三种方式,如下:
- Class类的forName()方法,动态加载,运行时,开始装入类, 并做类的静态初始化
- 对象的getClass()方法,静态加载(编译时已加载)
- .class语法, 静态加载(编译时已加载)
通过反射创建对象
有两种方式,如下:
- 通过Class对象的newInstance()方法创建,这种方式只能调用无参构造方法;
- 通过Constructor对象的newInstance()方法创建,这种方式适用于有参构造方法,并且还可以破坏单例模式,调用私有构造方法;
所以,通常来讲,第二种方式比第一种使用范围更广
Class对象调用newInstance()方法示例
package dai;
class TestDai{}public class Test{ public static void main(String args[]) { try { Class<?> c = Class.forName("dai.TestDai"); TestDai td = (TestDai) c.newInstance(); } catch (Exception e) { System.out.println(e); } }}
Constructor对象调用newInstance()方法示例
注意这里可以根据传入参数的类型来得到指定的构造方法,还可以改变构造方法的访问权限限制。
package dai; import java.lang.reflect.Constructor; class TestDai{ private String msg; void message() { System.out.println("Hello" + msg); } private Simple(String msg){ this.msg = msg; } } public class Test { public static void main(String args[]) { try { Class<?> c = Class.forName("dai.TestDai"); Constructor<?> con = c.getDeclaredConstructor(String.class); con.setAccessible(true); //设置可访问权限的限制 TestDai td = (TestDai) con.newInstance("Java"); td.message(); } catch (Exception e) { System.out.println(e); } } }
通过反射调用私有方法
通过反射,我们可以调用其它类的私有方法,主要涉及java.lang.Class和java.lang.reflect.Method类;
其中主要是用到了Method类的setAccessible方法和invoke方法,前者修改访问权限,后者调用方法。
通过调用有参私有方法示例:
package dai; import java.lang.reflect.Method; class A { private void message(int n) { System.out.println(n); } } class Test { public static void main(String args[]) throws Exception { Class<A> a = A.class; Object obj = a.newInstance(); Method m = a.getDeclaredMethod("message", new Class[]{ int.class }); m.setAccessible(true); m.invoke(obj, 8); } }