什么是Class类
Class 类是在Java语言中定义一个特定类的实现。一个类的定义包含成员变量,成员方法,还有这个类实现的接口,以及这个类的父类。Class类的对象用于表示当前运行的 Java 应用程序中的类和接口。 比如:每个数组均属于一个 Class 类对象,所有具有相同元素类型和维数的数组共享一个Class 对象。基本的 Java 类型(boolean, byte, char, short,int, long, float 和 double) 和 void 类型也可表示为 Class 对象。
我们都知道所有的java类都是继承了object这个类,在object这个类中有一个方法:getclass().这个方法是用来取得该类已经被实例化了的对象的该类的引用,这个引用指向的是Class类的对象(呵呵,有点别扭)。我们自己无法生成一个Class对象(构造函数为private),而这个Class类的对象是在当各类被调入时,由 Java 虚拟机自动创建 Class 对象,或通过类装载器中的 defineClass 方法生成。 我们生成的对象都会有个字段记录该对象所属类在CLass类的对象的所在位置。我们可以把每个Class类的对象当做众多类的代理。而且在每个Class类对象中有会有字段记录他引用的这个类的类加载器。如果该字段为null,表示该类的加载器为bootstrap loader。如下图所示:
![](https://img.haomeiwen.com/i14945598/190079008bde95e8.png)
获取Class对象的三种方式
1.通过类名获取 类名.class
2.通过对象获取 对象名.getClass()
3.通过全类名获取 Class.forName(全类名)
forName(String classname)和 forName(Stringclassname,{}boolean initialze,ClassLoader loader)方法。该方法返回给定串名相应的Class对象。若给定一个类或接口的完整路径名,那么此方法将试图定位、装载和连接该类。若成功,返回该类对象。否则,抛出ClassNotFoundException异常。例如,下面代码段返回名为java.lang.Thread的运行Class描述器。Classt=Class.forName("java.lang.Thread");此方法是需要指定类加载器的,当用到仅有一个String参数的forName方法时,Class对象将默认调用当前类加载器作为加载器和将第二参数为true。第二个参数说明:如果是false时,调用forName方法只是在命令类加载器载入该类,而不初始化该类的静态区块,只有当该类第一次实例化时,静态区块才被调用。当为true时,则载入时就调用静态区块。
public class ReflectionTest {
@Test
public void testClass() throws ClassNotFoundException {
Class clazz = null;
//1.通过类名
clazz = Person.class;
//2.通过对象名
//这种方式是用在传进来一个对象,却不知道对象类型的时候使用
Person person = new Person();
clazz = person.getClass();
//上面这个例子的意义不大,因为已经知道person类型是Person类,再这样写就没有必要了
//如果传进来是一个Object类,这种做法就是应该的
Object obj = new Person();
clazz = obj.getClass();
//3.通过全类名(会抛出异常)
//一般框架开发中这种用的比较多,因为配置文件中一般配的都是全类名,通过这种方式可以得到Class实例
String className=" com.atguigu.java.fanshe.Person";
clazz = Class.forName(className);
//字符串的例子
clazz = String.class;
clazz = "javaTest".getClass();
clazz = Class.forName("java.lang.String");
System.out.println();
}
}
Class的常用方法
Object newInstance()
调用缺省构造函数,返回该Class对象的一个实例
Object newInstance(Object []args)
调用当前格式构造函数,返回该Class对象的一个实例
Class getSuperClass()
返回当前Class对象的父类的Class对象
Class [] getInterfaces
获取当前Class对象的接口
ClassLoader getClassLoader()
返回该类的类加载器
Method [] getMethods
获取取clazz对应类中的所有方法,不能获取private方法,且获取从父类继承来的所有方法
Method[] getDeclaredMethods()
获取所有方法,包括私有方法,所有声明的方法,都可以获取到,且只获取当前类的方法
Method getDeclaredMethod("funcName", Object.class);
获取指定的方法, 需要参数名称和参数列表,无参则不需要写
Field[] getDeclaredFields();
获取所有字段,可以获取公用和私有的所有字段,但不能获取父类字段
Field getDeclaredField("name");
获取指定字段
Constructor<Object> [] getConstructors()
获取全部 Constructor 对象
Constructor<Object> getConstructor(Class class)
获取某一个Constructor,需要参数列表,参数代表构造方法的参数类型
Method的常用方法
method.invoke(param1,param2 ...)
param1表示执行哪个对象的方法,剩下的参数是执行方法时需要传入的参数
私有方法的执行,必须在调用invoke之前加上一句method.setAccessible(true);
Annotation getAnnotation(Class class)
获取指定名称的注解
Annotation [] getDeclaredAnnotations()
返回所有声明的注解
Field 的常用方法
field.get(object)
获取指定对象的指定字段的值
field.set(object, value);
设置指定对象的指定对象Field值
如果字段是私有的,不管是读值还是写值,都必须先调用setAccessible(true)
方法
Constructor的常用方法
newInstance/newInstance(Class ...)
调用构造器的newInstance() 方法创建对象
反射与泛型
定义一个泛型类:
public class DAO<T> {
private Class<T> tClass=null;
//根据id获取一个对象
T get(){
Type type=this.getClass().getGenericSuperclass();
if(type instanceof ParameterizedType){
ParameterizedType parameterizedType = (ParameterizedType) type;
Type [] arges = parameterizedType.getActualTypeArguments();
Type arg = arges[0];
if (arg instanceof Class){
tClass = (Class<T>) arg;
}
try {
if (tClass!=null){
Constructor<T> constructor=tClass.getConstructor(String.class,int.class);
return constructor.newInstance("abc",250);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
}catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return null;
}
}
再定义一个子类,继承这个泛型类:
public class PersonDAO extends DAO<Person> {
}
注意子类不许指定泛型的具体类型,泛型不能从调用处指定。
People类:
public class People {
public String name;
public int age;
public People() {
}
public People(String name, int age) {
this.name = name;
this.age = age;
}
}
使用时,用PeopleDao初始化
PeopleDao dao=new PeopleDao();
People people= dao.get();
网友评论