Class类
在程序运行的时候,Java运行时系统会为所有的对象维护一个被称为运行时的类型标识,这个信息跟踪着每一个对象所属的类,JVM利用运行时类型的信息选择相应的方法执行,保存这些信息的类被称为Class类(java.lang.Class);
利用反射生成类的实例
//定义一个User类
public class User{
//User类的两个属性
private Integer id;
private String name;
//...省略的get()\set()方法
}
//测试类
public class App {
public static void main(String[] args) throws Exception{
//填写类的全限定名称(既是包括包名.类名),得到保存这个类(User)信息的Class
Class clazz = Class.forName("demo.User");
//调用Class类中的newInstance()方法为User生成对象实例
User user = (User)clazz.newInstance();
}
}
特别注意
newInstance();方法调用的是无参构造器来创建对象实例,如果这个类没有无参构造器就是抛出以下异常:
java.lang.InstantiationException: demo0.User
通过反射生成类的实例的实际应用
* struts2中Action的配置文件的class属性,就是利用类的全限定名称来反射生成类的实例
* hibernate中实体的配置文件中的class属性同理
* spring中的配置文件也是通过反射来得到类的实例
利用反射分析类的能力
在java.lang.reflection包中有三个类:
* Field : 描述类的域
* Method : 描述类中定义的方法
* Constructor : 描述类的构造器
Field
- 得到类中定义的属性域
//根据上述的User类做测试
@Test
public void testFiled() throws Exception {
//得到封装User类信息的Class类
Class<?> clazz = Class.forName("demo0.User");
//调用getDeclaredFields()方法得到User类中所声明的所有属性,包括private
Field[] fields = clazz.getDeclaredFields();
//遍历
for (Field field : fields) {
System.out.println(field.getName());//得到属性名称
}
}
@Test
public void testFiled2() throws Exception {
Class<?> clazz = Class.forName("demo0.User");
//不能够得到private修饰符修饰的属性
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println(field.getName());
}
}
Field类的实际应用
- 组装一个SQL语句:select id ,name from user
@Test
public void testSql() throws Exception {
Class<?> clazz = Class.forName("demo0.User");
//利用StringBuilder组装字符串:sql
StringBuilder sql = new StringBuilder();
//得到类中所有声明的属性
Field[] fields = clazz.getDeclaredFields();
//执行完for循环后:sql="select id,name,"
sql.append("select ");
for (Field field : fields) {
sql.append(field.getName());
sql.append(",");
}
//去掉sql中的最后一个逗号,此时的sql="sql="select id,name"
String ss = sql.substring(0, sql.length()-1);
StringBuilder sb = new StringBuilder(ss);
//得到User类的简单名称,此时sql="select id,name from user"
sb.append(" from " + clazz.getSimpleName().toLowerCase());
//打印
System.out.println(sb.toString());
}
Field类中的其他方法
- class getType() : 得到这个字段声明时的类型
- int getModifiers() : 得到这个字段的修饰符
- …..
Method
- 得到类中所定义的方法
@Test
public void testMethod() throws Exception{
Class<?> clazz = Class.forName("demo0.User");
//包含本类的所有方法,包括private修饰的方法
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
//打印出方法名:setId getId setName getName
System.out.println(method.getName());
}
}
@Test
public void testMethod2() throws Exception{
Class<?> clazz = Class.forName("demo0.User");
//包括父类的方法一并获得,public修饰的方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.print(method.getName());
}
}
Method类中的其他方法
- class[] getParameterTypes() : 按照声明顺序返回 Class 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型。
- …
Constructors
- 得到类的构造方法中的参数
@Test
public void testConstructor() throws Exception {
Class<?> clazz = Class.forName("demo0.User");
Constructor<?>[] cons = clazz.getDeclaredConstructors();
for (Constructor<?> constructor : cons) {
//得到构造方法中的参数类型数组
Class<?>[] c = constructor.getParameterTypes();
for (Class<?> class1 : c) {
System.out.println(class1.getName());
}
}
}
综合实例
//TODO