反射
定义:
反射允许对封装类的字段,方法和构造 函数的信息进行编程访问
图来自黑马程序员
获取class对象的三种方式:
1)Class.forName("全类名")
2)类名.class
3) 对象.getClass()
图来自黑马程序员
package com.lazyGirl.reflectdemo;
public class MyReflectDemo1 {
public static void main(String[] args) throws ClassNotFoundException {
//最常见
Class clazz = Class.forName("com.lazyGirl.reflectdemo.Student");
System.out.println(clazz);
Class clazz2 = Student.class;
System.out.println(clazz2);
System.out.println(clazz == clazz2);
Student student = new Student();
Class clazz3 = student.getClass();
System.out.println(clazz3);
System.out.println(clazz == clazz3);
}
}
输出:
获取构造方法:
图来自黑马程序员
package com.lazyGirl.reflectdemo.demo1;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;
public class Demo1 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class clazz = Class.forName("com.lazyGirl.reflectdemo.demo1.Student");
Constructor[] cons = clazz.getConstructors();
for (Constructor c : cons) {
System.out.println(c);
}
System.out.println();
Constructor[] cons1 = clazz.getDeclaredConstructors();
for (Constructor c : cons1) {
System.out.println(c);
}
System.out.println();
Constructor cons2 = clazz.getDeclaredConstructor();
System.out.println(cons2);
System.out.println();
Constructor cons3 = clazz.getDeclaredConstructor(String.class);
System.out.println(cons3);
System.out.println();
Constructor cons4 = clazz.getDeclaredConstructor(int.class);
System.out.println(cons4);
System.out.println();
Constructor cons5 = clazz.getDeclaredConstructor(String.class, int.class);
System.out.println(cons5);
int modifiers = cons5.getModifiers();
System.out.println(modifiers);
System.out.println();
Parameter[] parameters = cons5.getParameters();
for (Parameter p : parameters) {
System.out.println(p);
}
cons5.setAccessible(true);
Student stu = (Student) cons5.newInstance("hhh",16);
System.out.println(stu);
}
}
输出:
获取成员变量:
图来自黑马程序员
package com.lazyGirl.reflectdemo.demo2;
import java.lang.reflect.Field;
public class Demo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
Class clazz = Class.forName("com.lazyGirl.reflectdemo.demo2.Student");
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println(field.getName());
}
System.out.println();
Field[] declaredFields = clazz.getDeclaredFields();
for (Field field : declaredFields) {
System.out.println(field.getName());
}
System.out.println();
Field gender = clazz.getField("gender");
System.out.println(gender);
System.out.println();
Field declaredName = clazz.getDeclaredField("name");
System.out.println(declaredName);
System.out.println();
int modifiers = declaredName.getModifiers();
System.out.println(modifiers);
String name = declaredName.getName();
System.out.println(name);
System.out.println();
Class<?> type = declaredName.getType();
System.out.println(type);
Student student = new Student("hhh",16,"女");
declaredName.setAccessible(true);
Object value = declaredName.get(student);
System.out.println(value);
declaredName.set(student,"hhhh");
System.out.println(student);
}
}
输出:
获取成员方法:
图来自黑马程序员
package com.lazyGirl.reflectdemo.demo3;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
public class Demo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class clazz = Class.forName("com.lazyGirl.reflectdemo.demo3.Student");
//包含父类的方法
// Method[] methods = clazz.getMethods();
//不能获取父类方法,但是可以访问私有方法
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
Method method = clazz.getMethod("eat", String.class);
System.out.println(method);
int modifiers = method.getModifiers();
System.out.println(modifiers);
String name = method.getName();
System.out.println(name);
Parameter[] parameters = method.getParameters();
for (Parameter parameter : parameters) {
System.out.println(parameter);
}
Class[] exceptions = method.getExceptionTypes();
for (Class exception : exceptions) {
System.out.println(exception);
}
Student student = new Student();
method.invoke(student,"cake");
}
}
Student类:
package com.lazyGirl.reflectdemo.demo3;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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 void sleep(){
System.out.println("sleep");
}
public void eat(String food) throws InterruptedException,ClassCastException{
System.out.println("eat " + food);
}
public void eat(String food, int time){
System.out.println("eat " + food + " " + time);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
输出:
作用:
获取一个类里面所有的信息,获取到了之后,再执行其他业务逻辑
结合配置文件,动态的创建对象并调用方法
package com.lazyGirl.reflectdemo.demo5;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Properties prop = new Properties();
FileInputStream fis = new FileInputStream("pro.properties");
prop.load(fis);
fis.close();
System.out.println(prop);
String classname = (String) prop.get("classname");
String methdName = (String) prop.get("method");
System.out.println(classname);
System.out.println(methdName);
Class clazz = Class.forName(classname);
Constructor constructor = clazz.getConstructor();
Object o = constructor.newInstance();
System.out.println(o);
Method method = clazz.getDeclaredMethod(methdName);
method.setAccessible(true);
method.invoke(o);
}
}
properties文件:
classname=com.lazyGirl.reflectdemo.demo5.Student
method=study
输出:
动态代理:
无侵入式的给代码增加额外的功能
程序为什么需要代理:对象身上干的事太多,可以通过代理来转移部分职业
对象有什么方法想被代理,代理就一定要有对应的方法
java通过接口保证对象和代理
格式:
图来自黑马程序员