1、java中万物皆对象,类也是一种对象,是Class类的实例对象
2、获取类的类类型(class type)的三种方法
Class c1 = A.class;
Class c2 =a.getClass();
Class c3 =Class.forName(“类路径+类名称”);
编译时刻加载类是静态加载类、运行时刻加载类是动态加载类。Class.forName是动态加载类,跳过编译期在运行期执行
3、通过类的类类型创建对象
A a =(A) c1.newInstance();
4、通过类的类类型获取类的信息
/**
* 获取object所属类的成员函数
* @param object
*/
public static void printClassMethodMessage(Object object){
//要获取类的信息,首先获取类的类类型
Class c = object.getClass();
//获取类的名称
System.err.println(c.getName());
/**
* 获取成员函数
* 一个成员函数就是一个Method对象
* getMethods()获取的是所有public函数,包括父类继承来的
* getDeclaredMethods()获取的是所有该类自己声明的方法,无关访问权限
*/
Method[] ms = c.getMethods();
for (int i=0;i<ms.length;i++){
//得到方法返回值类型的类类型
Class<?> returnType = ms[i].getReturnType();
System.err.println(returnType.getName());
//得到方法的名称
System.err.println(ms[i].getName());
//获取参数类型:得到的是参数列表的类型的类类型
Class<?>[] parameterTypes = ms[i].getParameterTypes();
for (Class class1:parameterTypes){
System.err.println(class1.getName());
}
}
}
/**
* 获取object所属类的成员变量
* @param object
*/
public static void printFieldMessage(Object object){
Class c = object.getClass();
//获取修饰这个类的相应注解:比如TableName
TableName annotation = (TableName) c.getAnnotation(TableName.class);
/**
* 获取成员变量
* 一个成员变量就是一个Field对象
* getFields()获取的是所有public成员变量,包括父类继承来的
* getDeclaredFields()获取的是所有该类自己声明的成员变量,无关访问权限
*/
Field[] fs = c.getDeclaredFields();
for (Field field : fs){
//获取这个成员变量的Id注解,有的成员变量id注解为null,有的不为null
Id id = field.getAnnotation(Id.CLASS);
//将成员变量的pvivate改成可用,这样可以操作这个成员变量
field.setAccessible(true);
//得到成员变量的类型的类类型
Class<?> fieldType = field.getType();
String typeName = fieldType.getSimpleName();
//得到成员变量的名称
String fieldName = field.getName();
System.err.println(typeName+" "+fieldName);
//得到该对象这个成员变量所对应的值
try {
String value = (String) field.get(object);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
field.setAccessible(false);
}
}
/**
* 获取object所属类的构造函数
* @param object
*/
public static void printConMessage(Object object){
Class c = object.getClass();
/**
* 获取构造函数
* 一个构造函数就是一个Constructor对象
* getConstructors()获取的是所有public构造函数,包括父类继承来的
* getDeclaredConstructors()获取的是所有该类自己声明的构造函数,无关访问权限
*/
Constructor[] cs = c.getDeclaredConstructors();
for (Constructor constructor : cs){
System.err.println(constructor.getName());
//获取参数类型:得到的是参数列表的类型的类类型
Class[] parameterTypes = constructor.getParameterTypes();
for (Class class1 : parameterTypes){
System.err.println(class1.getName());
}
}
}
5、通过method调用方法
public static void main(String[] args) {
A a = new A();
Class<? extends A> c = a.getClass();
try {
/**
* c.getMethod("方法名","参数列表的类类型")
* getMethod获取的是public方法
* getDeclaredMethod获取自己声明的方法
*/
Method m = c.getMethod("print", int.class, int.class);
// Method m = c.getMethod("print", new Class[]{int.class, int.class});
//m.invoke("对象","具体的参数值")
Object o = m.invoke(a, 10, 20);
// Object o = m.invoke(a, new Object[]{10, 20});
} catch (Exception e) {
e.printStackTrace();
}
}
public class A {
public void print(int a,int b){
System.err.println(a+b);
}
}
Class、Method、Field等类中的所有方法都是运行期才有效的方法,可以无视编译期
补充:泛型只在编译期有效,跳过编译期泛型就无效了,这时往容器里存任何类型都可以
public static void main(String[] args) {
List<String> list = new ArrayList<>();
System.err.println(list.size());
Class<? extends List> c = list.getClass();
try {
//Class、Method的方法在运行期有效,可以无视编译期,所以插入int类型的数据,依然不报错
Method add = c.getMethod("add", Object.class);
add.invoke(list,20);
System.err.println(list.size());
System.err.println(list);
} catch (Exception e) {
e.printStackTrace();
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/153467.html