反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射缺点:尽管反射非常强大,但也不能滥用。如果一个功能可以不用反射完成,那么最好就不用。
1.性能第一
反射包括了一些动态类型,所以JVM无法对这些代码进行优化。因此,反射操作的效率要比那些非反射操作低得多。我们应该避免在经常被执行的代码或对性能要求很高的程序中使用反射。
2.安全限制
使用反射技术要求程序必须在一个没有安全限制的环境下运行。
3.内部暴露
由于反射允许代码执行一些在正常情况下不被允许的操作(比如访问私有的属性和方法),所以使用反射可能会导致意外之外的副作用–代码有功能上的错误,降低可移植性。反射代码破坏了抽象性,因此当平台发生改变的时候,代码的行为就有可能也随着变化。
如何获取反射模板(说明书)
public static void getClazz(){
try {
//类.class
Class clazz=TestBean.class;
//Class.forName(包名+类名)
// Class clazz=Class.forName("com.cdsxt.vo.TestBean");
//对象.getClass()
// TestBean bean=new TestBean();
// Class clazz=(Class<TestBean>) bean.getClass();
//获取类名
//反射对象.getSimpleName() 获取类名
String name=clazz.getSimpleName();
System.out.println(name);
//通过反射模板获取对象 本质上 就是 new 类名()
// Object obj=clazz.newInstance();
// System.out.println(obj instanceof TestBean);
} catch (Exception e) {
e.printStackTrace();
}
}
//通过反射模板 获取多个属性
public static void testFields(){
try {
//获取反射模板
Class clazz=TestBean.class;
//获取多个属性
// Field[] fields=clazz.getFields();
Field[] fields=clazz.getDeclaredFields();
System.out.println(fields.length);
for(Field field:fields){
//获取属性名
String fieldName=field.getName();
//获取属性的类型
Class type=field.getType();
System.out.println(fieldName+"---"+type);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//通过反射模板 获取单个属性
public static void testField(){
try {
//获取反射模板
Class clazz=TestBean.class;
//创建对象
Object obj=clazz.newInstance();
//获取单个属性
/* Field phone=clazz.getField("phone");
// System.out.println(phone.getName()+"---"+phone.getType());
//给属性存值 对象.set属性名(值)
phone.set(obj, "13558832140");
//取值 对象.get属性名();
Object phoneVal=phone.get(obj);
System.out.println(phoneVal);*/
//静态对象写null
/*Field gender=clazz.getField("gender");
gender.set(null, "保密");
Object genderVal=gender.get(null);
System.out.println(genderVal);*/
Field id=clazz.getDeclaredField("id");
//取消java安全性监测
id.setAccessible(true);
id.set(obj, 9527);
Object idVal=id.get(obj);
id.setAccessible(false);
System.out.println(idVal);
} catch (Exception e) {
e.printStackTrace();
}
}
}
//通过反射模板获取多个方法
public static void testMethods(){
try {
Class clazz=TestBean.class;
// Method[] methods=clazz.getMethods();
Method[] methods=clazz.getDeclaredMethods();
System.out.println(methods.length);
for(Method method:methods){
//获取方法名
String name=method.getName();
System.out.println(name);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//通过反射模板获取单个方法
public static void testMethod(){
try {
Class clazz=TestBean.class;
Object obj=clazz.newInstance();
/*Method test=clazz.getMethod("test");
//调用方法 对象.方法名(实参列表)
test.invoke(obj);*/
//类.方法名(实参列表)
// Method hello=clazz.getMethod("hello", String.class);
// hello.invoke(null, "张志明");
Method add=clazz.getDeclaredMethod("add", int.class,int.class);
add.setAccessible(true);
Object result=add.invoke(obj, 300,300);
System.out.println(result);
add.setAccessible(false);
} catch (Exception e) {
e.printStackTrace();
}
}
//通过反射模板获取多个构造器
public static void testConstructors(){
try {
Class clazz=TestBean.class;
// Constructor[] cons=clazz.getConstructors();
Constructor[] cons=clazz.getDeclaredConstructors();
System.out.println(cons.length);
} catch (Exception e) {
e.printStackTrace();
}
}
//通过反射模板获取单个构造器
public static void testConstructor(){
try {
Class clazz=TestBean.class;
// Constructor<TestBean> con=clazz.getConstructor();
//通过构造器创建对象
//本质上等于 clazz.newInstance() new TestBean()
// TestBean bean=con.newInstance();
// System.out.println(bean);
// Constructor<TestBean> con=clazz.getConstructor(int.class,String.class);
// TestBean bean=con.newInstance(9527,"zzz");
// System.out.println(bean.getName()+"--"+bean.getId());
Constructor<TestBean> con=clazz.getDeclaredConstructor(String.class);
con.setAccessible(true);
TestBean bean=con.newInstance("zzz");
System.out.println(bean.getName());
} catch (Exception e) {
e.printStackTrace();
}
}
}