Class类和反射
Class 类是什么?
Class
类是java
从1.2
开始引入的一个特殊的类.在Object
类中,getClass()
方法的返回值就是Class
类型的.即,java中的每一个类都可以获取自己的Class
对象.
那么,Class
类是做什么的呢?
在javaDoc
中,是这么定义的
Instances of the class Class represent classes and interfaces in a running Java application. An enum is a kind of class and an annotation is a kind of interface. Every array also belongs to a class that is reflected as a Class object that is shared by all arrays with the same element type and number of dimensions. The primitive Java types (boolean, byte, char, short, int, long, float, and double), and the keyword void are also represented as Class objects.
Class
是java
中的类或接口在运行的java程序中的一个类型实例.
包含一个类或接口中的所有字段,方法,构造函数.
怎么使用Class?
1. 获取Class
java
中,获取Class
对象有三种方法.
-
Object.getClass()
由于java
中所有类都是Object
的子类,所以所有方法都可以使用这个方法进行获取.
A a = new A();
Class aClass = a.getClass();
-
Class.forName(String value)
value 必须是类的带完整包名的名称.
这是Class
类中的一个静态方法,也是框架中最常用的一个方法
Class a = Class.forName("packageA.a");
Class tClass = Class.forName("java.lang.Thread");
-
类.class
;
每个类都可以通过.class
的方式来获取Class
Class aClass = A.class;
三种方法的区别
在java中,加载一个类可以简单的看为三个步骤:
- 加载
- 连接
- 初始化
在上面三种方法中,只有Class.forName()
方法加载的类是三个步骤全部完成的,而类.class
不会执行到初始化,只在访问类中的静态数据时,才会进行初始化过程.
2. 使用Class
Class
的常见使用是和反射一起进行的.反射是指在java.lang.reflect
下的一系列软件.
通过和反射结合,可以获取一个类中的所有字段,方法,构造器并访问,并且不受访问限制符的约束.
构造器函数
获取
public Constructor<?>[] getDeclaredConstructors() //获取所有构造器
Constructor[] constructors = cl.getConstructors(); //获取所有public的构造器
public Constructor<T> getConstructor(Class<?>... parameterTypes) //获取指定参数的public的构造器
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) //获取指定参数的任意访问权限的构造器
使用
Class aClass = A.class;
Constructor[] constructors = aClass.getConstructors();
System.out.println(constructors.length);
Constructor[] constructors1 = aClass.getDeclaredConstructors();
System.out.println(constructors1.length);
Constructor constructor = aClass.getDeclaredConstructor();
constructor.newInstance();
Constructor constructor1 = aClass.getDeclaredConstructor(String.class);
constructor1.newInstance("world");
}
输出结果为:
0
2
no-pro A init
String A init world
方法
获取
获取方法的函数为:
public Method[] getMethods() //返回类的所有public方法,包含父类的可继承的方法
public Method getMethod(String methodName, Class<?>... parameterTypes)
// 返回指定methodName和参数类型的方法
public Method[] getDeclaredMethods() //获取所有方法,包含父类的可继承方法
public Method getDeclareMethod(String methodName, Class<?>... parameterTypes)
使用
public class A {
private String name;
private String sex;
public void show() {
System.out.println("this is show method");
}
public void show1(String name) {
System.out.println("this is show1 method + " + name);
}
public static void main(String[] args) throws Exception{
Class aClass = A.class;
Method[] methods = aClass.getMethods();
System.out.println(methods.length);
A a = (A)aClass.newInstance();
Method methodShow = aClass.getMethod("show");
methodShow.invoke(a);
Method methodShow1 = aClass.getMethod("show1", String.class);
methodShow1.invoke(a, "world");
}
字段
获取
public Field[] getFields()
public Field getField(String name)
public Field getDeclaredFields()
public Field getDeclaredField(String name)
使用
public class A {
public String name;
public String sex;
@Override
public String toString() {
return "A{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
'}';
}
public static void main(String[] args) throws Exception{
Class aClass = A.class;
Field fName = aClass.getField("name");
Field fSex = aClass.getField("sex");
A a = (A) aClass.newInstance();
fName.set(a, "zhangsan");
fSex.set(a, "nan");
System.out.println(a);
}
}
.setAccessible
当我们在访问修改private修饰的方法,函数,构造器时,默认是不允许我们进行修改的,这时就需要执行.setAccessible(true)
方法,来解开对private类型的保护,强制访问.