一、什么情况下需要使用反射?
答:
在编译时无法知道该对象或类属于哪些类,此时就可用反射了。
二、Class 类的作用及其主要功能?
答:
类是对象的设计图,Person 类可以创建多个对象,Class 类是类的设计图也就是Person类等都是一个Class类的实例,在运行时都对应着一个 Class 对象。
Class 类提供了很多方法:
比如反射技术常用到的 Class.forName(“包.类”);这样可以获取该类的 Class 对象。通过这个 Class 对象,我们可以调用该类的方法,属性,构造方法…等
三、如何使用反射创建一个对象?
答:
一种:
public static void main(String[] args) {
try {
//使用Class.forName()
Class personClass = Class.forName("com.str.strs.Person");
Person newInstance = (Person) personClass.newInstance();
//使用xxx.getClass()
String s = "Person";
Class personClass1 = s.getClass();
Person newInstance1 = (Person) personClass1.newInstance();
//使用xxx.class
Class personClass2 = Person.class;
Person newInstance2 = (Person) personClass2.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
二种:
//使用Class.forName()
Class personClass = Class.forName("com.str.strs.Person");
//实体列必须有对应的构造方法
Constructor constructor = personClass.getConstructor(String.class);
Person newInstance = (Person) constructor.newInstance("构造方法");
//其他同上
四、如何使用反射操作属性?
答:
通过 Class 对象获得属性的方法有
1、获取 public 的属性:object.getFields()
2、获取所有的属性: object.getDeclaredFields()
3、根据属性名称获取 public 的属性信息: object.getField(“age”);
4、根据属性名称获取属性的信息:object.getDeclaredField(“name”);
Class personClass =Class.forName("MyReflect.MyPersonText");
System.out.println(“获取所有的公共属性.并打印**************”);
Field[] field1 = personClass.getFields();
for(Field f:field1){
System.out.println(f.getName());
}
五、如何使用反射执行方法?
答:
1、方法的操作 method.invoke(对象,参数列表)
2、获取方法 由名称和参数列表类决定
3、getMethod(name, parameterTypes) 获取的public的方法
4、getDeclaredMethod(name, parameterTypes) 获取自己声明的方法
//有参数的构造方法
Class A1 =MyPersonText.class;
try {
Method mt =A1.getMethod("tell", String.class);
Constructor con = A1.getConstructor(null);
MyPersonText we =(MyPersonText)con.newInstance(null);
mt.invoke(we, "自行车");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/**
普通的方法
*/
Students students = new Students();
Class stClass = students.getClass();
try {
//这两种方法都可使用
System.out.println("----------一种---------------");
Method method = stClass.getMethod("start",new Class[]{int.class,int.class});
//如有返回就返回的对应的返回值,没有则为null
Object invoke = method.invoke(students, new Object[]{1,2});
System.out.println(invoke);
System.out.println("----------二种---------------");
Method method1 = stClass.getMethod("start",String.class,String.class);
Object invoke2 = method1.invoke(students, "小张","小组");
System.out.println(invoke2);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
六、如何使用反射操作方法名?
答:
1、getMethods()方法是获取所有Public 修饰的方法,包括父类的
2、getDeclaredMethods()获取的是所有本类声明的方法,不包括父类的
Class stClass = String.class;
Method[] methods = stClass.getMethods();
for (int i = 0; i < methods.length; i++) {
// 获取方法的返回值类型的类类型
Class returnType = methods[i].getReturnType();
System.out.print(returnType.getName() + " ");
// 获取方法的名称
System.out.print(methods[i].getName() + "(");
// 获取参数的类型-->参数列表的类型的类类型
Class[] parameterTypes = methods[i].getParameterTypes();
for (Class class1 : parameterTypes) {
System.out.print(class1.getName() + " ");
}
System.out.print(")");
System.out.println();
}
七、反射的优缺点有哪些?
答:
优点
1、反射提高了 Java程序的灵活性和扩展性,降低耦合性,提高自适应能力。它允许程序创建和控制任何类的对象,无需提前硬编码目标类。
2、许多流行的开源框架例如Struts、Hibernate、Spring在实现过程中都采用了该技术。
缺点
1、性能问题:
使用反射基本上是一种解释操作,字段和方法接入时要远慢于直接代码。因此 Java 反射机制主要应用在对灵活性和扩展性要求很高的系统框架上,普通程序不建议使用。
2、使用反射会模糊程序内部逻辑:
开发人员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂
八、【编程题】如何使用反射越过泛型进行添加数据?
答:
ArrayList<String> array=new ArrayList<String>();
array.add("小张");//只能输入String类型的
ArrayList array1=new ArrayList();
array1.add(11);
Class ca1=array1.getClass();
Class ca=array.getClass();
System.out.println(ca1==ca);
/**
* ca1==ca为true 说明集合的泛型只是在输入的时候生效,而在编译的时候有效
* 越过编译就无效了
* */
//反射进行越过泛型
try {
Method method = ca.getMethod("add", Object.class);
method.invoke(array, 123);
//array 中有字符串和数字 方式泛型是String(反射越过泛型)
System.err.println(array);
} catch (Exception e) {
e.printStackTrace();
}