Java反射的简单使用
前言:什么是java反射?
? JAVA机制反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
使用Java反射的三种方式
- 对象名 . getClass();
- 类名 . class;
- Class . forName( " 类的路径 " )(常用)
1. 创建一个MyTest类,封装私有属性,使用反射来操作MyTest类
package cn.kgc.util;
public class MyTest {
private int id;
private String name;
private int age;
private void test(int ids){
System.out.println("ids = " + ids+ids);
}
public MyTest() {
}
@Override
public String toString() {
return "MyTest{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
2. 使用第一种方式 “对象名 . getClass();” ,获取并使用MyTest类的私有方法"test"
@Test
public void S3() throws InvocationTargetException, IllegalAccessException {
MyTest myTest = new MyTest();
Class<? extends MyTest> aClass = myTest.getClass();
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println("declaredMethod = " + declaredMethod.getName());
declaredMethod.setAccessible(true);
if (declaredMethod.getName() == "test"){
declaredMethod.invoke(myTest,1);
}
}
}
------------------------------------------------ S3 输出数据 --------------------------------------------------
declaredMethod = toString
declaredMethod = getName
declaredMethod = getId
declaredMethod = setName
declaredMethod = test
ids = 11 //这是test方法的打印结果
declaredMethod = setId
declaredMethod = setAge
declaredMethod = getAge
3. 使用第二种方式 “类名 . class;” ,获取并使用MyTest类的私有方法"test"
@Test
public void S1() throws InvocationTargetException, IllegalAccessException {
Class b = MyTest.class;
Method[] methods = b.getDeclaredMethods();
for (Method method : methods) {
method.setAccessible(true);
if (method.getName()=="test"){
MyTest myTest = new MyTest();
method.invoke(myTest,1);
}
}
}
4. 使用第三种方式 “Class . forName(String pathName )” ,获取并使用MyTest类的私有方法"test"
@Test
public void S4() throws ClassNotFoundException, InvocationTargetException, IllegalAccessException {
Class<?> aClass = Class.forName("cn.kgc.util.MyTest");
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
declaredMethod.setAccessible(true);
if (declaredMethod.getName() == "test"){
MyTest myTest = new MyTest();
declaredMethod.invoke(myTest,3);
}
}
}
最后:Java封装和Java反射是不是冲突呢,Java反射会不会破坏Java封装的封装性?
?······ 首先,封装是将具体的实现细节隐藏,而把功能作为整体提供给类的外部使用,也就是说,公有方法能够完成类所具有的功能。当别人使用这个类时,如果通过反射直接调用私有方法,可能根本实现不了类的功能,甚至可能会出错,因此通过反射调用私有方法可以说是没有任何用处的,开发人员没有必要故意去破坏封装好的类。从这点上看,封装性并没有被破坏。(摘自百度问答) ······个人的见解:反射确实可以得到一切 类中的东西(包括私有的属性、方法等),但是或许不算是破坏封装,私有方法是为了让继承的类无法使用,避免调用那些被设为私有的方法出现一些不必要的错误。这就是封装性。反射虽然可以获取私有方法并使用方法,只能说是其功能强大,可以在保证在调用私有方法不会出现错误,但是并没有反射调用方法后,该方法就不是私有的了。他仍然是私有的,仍然在子类中不可见。
|