反射的概念
- 在运行状态中,对于任意一个类,能够获取这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
- 作用
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法);
在运行时调用任意一个对象的方法
Class类的常用方法
利用反射创建对象
System.out.println("----------------new方法创建对象----------------------");
People people = new People("zhangsan",168.11,45,120.33);
System.out.println(people.getHeight());
people.birthday();
System.out.println("-----------------反射创建对象第一种方式(该方式只能采用无参构造)----------------");
//若没有无参构造方法,将会抛异常
Class<People> cla = People.class;
//Class<People> people1 = people.getClass();
//Class<People> people1 = Class.forName("pojo.People");
try {
People people1 = cla.newInstance();
people1.birthday();
System.out.println(people1.getHeight());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println("-------------------反射创建对象第二种方式(该方式可以指定特定的构造方法)---------------");
try {
Constructor<People> constructor = cla.getConstructor(String.class,Double.class,Integer.class,Double.class);
People people2 = constructor.newInstance("lisi",175.1,19,120.11);
System.out.println(people2.getHeight());
people2.birthday();
} catch (Exception e) {
e.printStackTrace();
}
运行结果
---------------new方法创建对象----------------------
168.11
zhangsan今天过45岁生日
-----------------反射创建对象第一种方式(该方式只能采用无参构造)----------------
无名氏今天过99岁生日
199.4
-------------------反射创建对象第二种方式(该方式可以指定特定的构造方法)---------------
175.1
lisi今天过19岁生日
获取对象属性
System.out.println("-----------------------获取public属性-------------------------------------");
Field[] fields = cla.getFields();
for (Field field : fields) {
System.out.println(field.getName());//获取对象名称
System.out.println(field.getClass());//获取class
System.out.println(field.getAnnotatedType().getType());
//返回一个 AnnotatedType 对象,该对象表示使用类型来指定由该字段对象表示的字段的类型
//通过其 getType() 方法,我们可以获取到对应的字段类型
System.out.println(field.getType());//获取对象类型
System.out.println("==========="+field.getModifiers());//获取修饰符的值
//什么都不加 是0 , public 是1 ,private 是 2 ,protected 是 4,static 是 8 ,final 是 16。
try {
System.out.println(field.get(new People()));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
System.out.println("-----------------------获取非public属性-------------------------------------");
try {
Field f = cla.getDeclaredField("age");
f.setAccessible(true);//不进行检查,操作private需要
System.out.println(f.get(new People()));
} catch (Exception e) {
e.printStackTrace();
}
/**
* 1.getField 只能获取public的,包括从父类继承来的字段。
* 2.getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。 (注: 这里只能获取到private的字段,但并不能访问该private字段的值,除非加上setAccessible(true))
*/
运行结果
-----------------------获取public属性-------------------------------------
name
class java.lang.reflect.Field
class java.lang.String
class java.lang.String
===========1
无名氏
weight
class java.lang.reflect.Field
class java.lang.Double
class java.lang.Double
===========1
120.12
-----------------------获取非public属性-------------------------------------
99
获取方法
System.out.println("---------------------------------获取public方法-------------------------------");
Method[] methods = cla.getMethods();
for (Method method : methods) {
System.out.println("=====方法名称====== "+method.getName());
System.out.println("=====方法返回类型====== "+method.getReturnType());
try {
System.out.println(methods[1].invoke(new People()));
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
System.out.println("---------------------------------获取非public方法-------------------------------");
Method[] declaredMethods = cla.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println("=====方法名===== "+declaredMethod.getName());
}
执行结果
---------------------------------获取public方法-------------------------------
=====方法名称====== toString
=====方法返回类型====== class java.lang.String
无名氏
=====方法名称====== getName
=====方法返回类型====== class java.lang.String
无名氏
=====方法名称====== setName
=====方法返回类型====== void
无名氏
=====方法名称====== getHeight
=====方法返回类型====== class java.lang.Double
无名氏
=====方法名称====== birthday
=====方法返回类型====== void
无名氏
=====方法名称====== setWeight
=====方法返回类型====== void
无名氏
=====方法名称====== getAge
=====方法返回类型====== class java.lang.Integer
无名氏
=====方法名称====== setAge
=====方法返回类型====== void
无名氏
=====方法名称====== setHeight
=====方法返回类型====== void
无名氏
=====方法名称====== getWeight
=====方法返回类型====== class java.lang.Double
无名氏
=====方法名称====== wait
=====方法返回类型====== void
无名氏
=====方法名称====== wait
=====方法返回类型====== void
无名氏
=====方法名称====== wait
=====方法返回类型====== void
无名氏
=====方法名称====== equals
=====方法返回类型====== boolean
无名氏
=====方法名称====== hashCode
=====方法返回类型====== int
无名氏
=====方法名称====== getClass
=====方法返回类型====== class java.lang.Class
无名氏
=====方法名称====== notify
=====方法返回类型====== void
无名氏
=====方法名称====== notifyAll
=====方法返回类型====== void
无名氏
---------------------------------获取非public方法-------------------------------
=====方法名===== toString
=====方法名===== getName
=====方法名===== setName
=====方法名===== getHeight
=====方法名===== birthday
=====方法名===== setWeight
=====方法名===== getAge
=====方法名===== setAge
=====方法名===== setHeight
=====方法名===== getWeight