反射
反射是发生在程序运行期的行为
Java 反射机制,可以实现以下功能:
①在运行时判断任意一个对象所属的类;
②在运行时构造任意一个类的对象;
③在运行时判断任意一个类所具有的成员变量和方法;
④在运行时调用任意一个对象的方法;
⑤生成动态代理
1.在创建类型的对象的时候,获取的是类型的Class对象的一个镜像|复制体
2.在一个类加载到内存时就会存在这个类型唯一的Class对象(方法,属性,构造器...)
3.如果能够拿到一个类型的Class对象,就可以操作这个类
获取一个类型的Class对象的方式:
1.类名.class
2.对象.getClass()
3.Class.forName(报名+类名|权限定名)
Class中的常用方法(操作构造器,操作方法,操作字段…)
代码实例:
public class ReflectDemo1 {
public static void main(String[] args) throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {
/*Person person=new Person();
person.test();*/
//通过反射创建对象实现动态改变对象
Properties pro=new Properties();
pro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.propertices"));
//反射创建对象 类名+包名
Person person=(Person) Class.forName(pro.getProperty("name")).newInstance();
person.test();
}
}
class Person{
public void test(){
System.out.println("我是person");
}
}
class Student extends Person{
public void test(){
System.out.println("我是student");
}
}
class Teacher extends Person{
public void test(){
System.out.println("我是Teacher");
}
}
public class ReflectDemo2 {
public static void main(String[] args) throws ClassNotFoundException {
//一个类型的 Class对象只有一个
//1.类名.class
Class<String> cla1=String.class;
System.out.println(cla1);//打印包名+类名
//2.对象.getClass();
Class cla2= "字符串".getClass();
System.out.println(cla1==cla2);//true一个类型的 Class对象只有一个
//3.Class.forName(包名+类名|权限定名);
Class cla3=Class.forName("java.lang.String");
System.out.println(cla2==cla3);
//4.getSuperclass();通过子类对象获取父类对象
Class cla4=cla3.getSuperclass();
System.out.println(cla4);
//获取基本数数据类型的对象
Class clsChar=char.class;
System.out.println(clsChar);
Class clsCharacter=Character.class;
System.out.println(clsCharacter);
//从包装类得到基本数据类型的Class对象 Character.TyPE;
System.out.println(char.class==Character.TYPE);
//Class对象的常用方法
Class<?>[] arr=cla1.getInterfaces();
System.out.println(Arrays.toString(arr));
//int getModifiers()返回此类或接口以整数编码的 Java 语言修饰符
System.out.println(Modifier.toString(cla1.getModifiers()));
//getName() 返回包名+类名
System.out.println(clsChar.getName());
//getSimpleName() 类名
System.out.println(cla1.getSimpleName());
//isPrimitive() 判定指定的 Class 对象是否表示一个基本类型
System.out.println(cla1.isPrimitive());
}
}
public class ReflectDemo3 {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//testConstructor(User.class);
testMethod(User.class);
}
//操作于构造器的方法
public static void testConstructor(Class cls) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
/*1.Constructor<T> getConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法*/
Constructor con1=cls.getConstructor(String.class);
System.out.println(con1);
/*2.Constructor<?>[] getConstructors()
返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法*/
Constructor[] con2=cls.getConstructors();
System.out.println(Arrays.toString(con2));
//Constructor->newInstance(Class...) 通过构造器创建对象
User user=(User) con2[1].newInstance("halo");
System.out.println(user);
/*3.Constructor getDeclaredConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法*/
Constructor con3=cls.getDeclaredConstructor(String.class,double.class);
System.out.println(con3);//获得default修饰的构造器
Constructor con4=cls.getDeclaredConstructor(String.class,int.class);
System.out.println(con4);//获得private修饰的构造器
con4.setAccessible(true);
User user2=(User) con4. newInstance("halo",38);
System.out.println(user2);
con4.setAccessible(false);
/*4.Constructor<?>[] getDeclaredConstructors()
返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法*/
Constructor[] con5 =cls.getDeclaredConstructors();
System.out.println(Arrays.toString(con5));
}
//操作方法
public static void testMethod(Class cls) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
/*1.Method getDeclaredMethod(String name, Class<?>... parameterTypes)
返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。 */
Method method=cls.getDeclaredMethod("hehe");
//创建对象
User user=(User) cls.getDeclaredConstructor().newInstance();
method.setAccessible(true);
method.invoke(user);
method.setAccessible(false);
/*2.Method[] getDeclaredMethods()
返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法*/
Method[] method2 =cls.getDeclaredMethods();
System.out.println(Arrays.toString(method2));
/*3.Method getMethod(String name, Class<?>... parameterTypes)
返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法*/
Method method3=cls.getMethod("haha");
method3.invoke(user);
/*4.Method[] getMethods()
返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法*/
}
}
class User{
public String name;
int age;
private double money;
public User() {
// TODO Auto-generated constructor stub
}
public User(String name) {
this.name = name;
}
private User(String name,int age) {
this.name = name;
this.age=age;
}
User(String name, double money) {
this.name = name;
this.money = money;
}
public User(String name, int age, double money) {
super();
this.name = name;
this.age = age;
this.money = money;
}
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;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
public void haha(){
System.out.println("hahahhaa...");
}
private static void hehe(){
System.out.println("hehhehhe...");
}
void xixi(){
System.out.println("xixixixi...");
}
@Override
public String toString() {
System.out.println("toString()方法执行啦");
return "User [name=" + name + ", age=" + age + ", money=" + money + "]";
}
}