反射 程序在运行时获得
会降低程序的运行效率,可以通过一些方法找到一些私有方法和属性,但是会打破程序,尽量不要使用,可以得到父类接口
一:创建一个实体类
public class Person {
private String name;
public int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 私有的方法
private void method1() {
System.out.println("我是私有的方法没有返回值");
}
private String method2() {
return "我是私有的,有返回值";
}
public void method3() {
System.out.println("共有,无返回值");
}
public String method4() {
return "共有 有返回值";
}
public void method5(String str) {
System.out.println("传入的值是:" + str);
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
二:反射使用
1:
/**
* 反射:
*
* 1. 使用反射创建对象
* 2. 调用成员变量,方法(私有的,共有的)
*
*/
public class ConstructorTest {
public static void main(String[] args) throws Exception {
//Person p = new Person();调用方法和属性。但是私有的调不到
//Class 类,和反射相关的类
//封装类每个类的构造,属性,方法
//有三种方式获取的一个类的class对象
// Class.forName(className) 通过forName方法加载类。 com.bwei.day14.Person
Class class1 = Class.forName("com.bwei.day14.Person");//返回值class 类型,就代表Person类
//获取构造
// class1.getConstructor(parameterTypes) 有参或者无参,无参,就什么也不填,有参,就将参数类型填上
// class1.getConstructors()--------获取全部的构造,返回的是数组
//获取无参构造
Constructor constructor = class1.getConstructor();//返回的是构造器
Object object = constructor.newInstance();//通过构造器构造 构造方法。
System.out.println(object);
//有参构造
Constructor constructor2 = class1.getConstructor(String.class,int.class);
Object object2 = constructor2.newInstance("张三",100);
System.out.println(object2);
}
}
2:
/**
* 获取属性
* 给属性复制
*/
public class FieldTest {
public static void main(String[] args) throws Exception {
//获取字节码文件
Class class1 = Class.forName("com.bwei.day14.Person");
// //获取属性 Field
// Field[] fields = class1.getFields();//获取所有的属性,但是只是公有的
// for (Field field : fields) {
// System.out.println(field);
// }
// System.out.println("-----------------------------------------");
class1.getField(name) 参数:变量名字
Field field = class1.getField("age");
// //赋值
p.setAge(10);
field.set(obj 要赋值的对象, value 要赋的值)
Constructor constructor = class1.getConstructor();
Object object = constructor.newInstance();
field.set(object, 1000);//给属性赋值
System.out.println(object);
System.out.println("-------------私有属性如何获取-------------------");
Class class2 = Class.forName("com.bwei.day14.Person");
// class2.getDeclaredField(name) 获取私有属性
Field field2 = class2.getDeclaredField("name");
//java.lang.IllegalAccessException 非法访问
field2.setAccessible(true);//设置变量可以访问。暴力破解
//赋值
field2.set(object, "李四");
System.out.println(object);
}
}
/**
*
* 通过反射:
* 1.获取共有方法
* 2.获取私有方法
*
*/
public class MethodTest {
public static void main(String[] args) throws Exception {
//获取字节码文件
Class class1 = Class.forName("com.bwei.day14.Person");
//获取共有的方法,包括父类的共有的方法
// Method[] methods = class1.getMethods();
// for (Method method : methods) {
// System.out.println(method);
// }
//获取method1
Method m1 = class1.getDeclaredMethod("method1", null);//参数1.方法名字。参数2. 方法的参数类型
m1.setAccessible(true);
//怎么调用invoke
Constructor constructor = class1.getConstructor();
Object object = constructor.newInstance();
// m1.invoke(obj,对象 args 参数列表)
// Exception in thread "main" java.lang.NoSuchMethodException: com.bwei.day14.Person.method1()
m1.invoke(object, null);
//有返回o值
Method method = class1.getDeclaredMethod("method2", null);
method.setAccessible(true);
Object obj = method.invoke(object, null);
System.out.println(obj);
}
}