反射
获取class对象的方法
public class Demo1 {public static void main(String[] args) throws ClassNotFoundException {//获取反射的三种方式//第一种 Class.forName(全类名)//用法:最为常用Class<?> clazz1 = Class.forName("Reflection.Student");
// System.out.println(clazz1);// class Reflection.Student//第二种//一般是当做 参数进行传递Class<Student> clazz2 = Student.class;System.out.println(clazz2==clazz1);//true//第三种//在有这个对象时使用Student s = new Student();Class<? extends Student> clazz3 = s.getClass();System.out.println(clazz3==clazz2);//true}
}
通过class获取构造方法,成员方法,成员变量
利用反射获取构造方法
public class Demo {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {//获取class对象Class<?> clazz = Class.forName("Reflection.Demo2.Student");//通过class对象获取构造方法对象//获取非私用的构造方法集合
// Constructor<?>[] cons1 = clazz.getConstructors();
// /**
// * public Reflection.Demo2.Student()
// * public Reflection.Demo2.Student(java.lang.String)
// */
// for (Constructor<?> constructor : cons1) {
// System.out.println(constructor);
// }//获取全部构造方法集合(包括私有构造)
// Constructor<?>[] cons2 = clazz.getDeclaredConstructors();
// /**
// * public Reflection.Demo2.Student()
// * public Reflection.Demo2.Student(java.lang.String)
// * protected Reflection.Demo2.Student(int)
// * private Reflection.Demo2.Student(java.lang.String,int)
// */
// for (Constructor<?> constructor : cons2) {
// System.out.println(constructor);
// }// //获取单个非私有构造方法(通过形参确定哪个构造方法)
// Constructor<?> con3 = clazz.getConstructor(String.class);
// //public Reflection.Demo2.Student(java.lang.String)
// System.out.println(con3);// //使用公开权限获取非公开会报错
// Constructor<?> con4 = clazz.getConstructor(int.class);
// /**
// * Exception in thread "main" java.lang.NoSuchMethodException: Reflection.Demo2.Student.<init>(int)
// * at java.base/java.lang.Class.getConstructor0(Class.java:3585)
// * at java.base/java.lang.Class.getConstructor(Class.java:2271)
// * at Reflection.Demo2.Demo.main(Demo.java:35)
// */
// System.out.println(con4);// Constructor<?> con5 = clazz.getDeclaredConstructor(int.class);
// //protected Reflection.Demo2.Student(int)
// System.out.println(con5);Constructor<?> con6 = clazz.getDeclaredConstructor(String.class,int.class);//private Reflection.Demo2.Student(java.lang.String,int)
// System.out.println(con6);// //通过构造方法获取修饰符,修饰符使用Int类型的数据进行指代,私有使用2表述
// int modifiers = con6.getModifiers();
// System.out.println(modifiers);// 2// //通过构造方法获取形参
// //获取这个构造方法所有的参数
// Parameter[] parameters = con6.getParameters();
// //java.lang.String arg0
// //int arg1
// for (Parameter parameter : parameters) {
// System.out.println(parameter);
// }// //获取这个构造方法所有参数的个数
// System.out.println(con6.getParameterCount());//2// //获取这个构造方法所有参数的类型
// Class<?>[] parameterTypes = con6.getParameterTypes();
// /**
// * class java.lang.String
// * int
// */
// for (Class<?> parameterType : parameterTypes) {
// System.out.println(parameterType);
// }// //通过构造方法获取名字
// System.out.println(con6.getName());//Reflection.Demo2.Student//通过构造方法获取对象//表述临时取消权限校验con6.setAccessible(true);//由于获取的构造方法为私有所以无法创建对象,但是使用上面的临时取消权限校验,可以使这个构造方法创建对象//这种方法叫暴力反射Student s = (Student) con6.newInstance("zhangsan", 18);System.out.println(s.toString());// Student{name = zhangsan, age = 18}}
}
public class Student {private String name;private int age;public Student() {}public Student(String name) {this.name = name;}protected Student( int age) {this.name = name;this.age = age;}private Student(String name, int age) {this.name = name;this.age = age;}
利用反射获取成员变量
public class Demo3 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {//获取class对象Class<?> clazz = Class.forName("Reflection.Demo3.Student");// Field[] fields = clazz.getFields();
// //由于不是获取全部只获取到了公开的
// //public java.lang.String Reflection.Demo3.Student.gender
// for (Field f : fields) {
// System.out.println(f);
// }//获取全部成员变量
// Field[] fields2 = clazz.getDeclaredFields();
// //private java.lang.String Reflection.Demo3.Student.name
// //private int Reflection.Demo3.Student.age
// //public java.lang.String Reflection.Demo3.Student.gender
// for (Field f : fields2) {
// System.out.println(f);
// }、//获取单个成员变量//public java.lang.String Reflection.Demo3.Student.genderField gender = clazz.getDeclaredField("gender");System.out.println(gender);//通过对象获取该成员方法的值Student s = new Student("lisi",18,"男");String gender1 = (String) gender.get(s);System.out.println(gender1);//男//修改改成员变量的值gender.set(s,"女");System.out.println(s);//Student{name = lisi, age = 18, gender = 女}}
}
public class Student {private String name;private int age;private String aaa(String name) throws IOException,NullPointerException, EOFException {System.out.println("aaa"+name);return "请问请问";}public void bbb(String name,int age){System.out.println("bbb"+name+age);}public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}/*** 获取* @return age*/public int getAge() {return age;}/*** 设置* @param age*/public void setAge(int age) {this.age = age;}public String toString() {return "Student{name = " + name + ", age = " + age + "}";}
}
public class Student {private String name;private int age;public String gender;public Student() {}public Student(String name, int age, String gender) {this.name = name;this.age = age;this.gender = gender;}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}/*** 获取* @return age*/public int getAge() {return age;}/*** 设置* @param age*/public void setAge(int age) {this.age = age;}/*** 获取* @return gender*/public String getGender() {return gender;}/*** 设置* @param gender*/public void setGender(String gender) {this.gender = gender;}public String toString() {return "Student{name = " + name + ", age = " + age + ", gender = " + gender + "}";}
}
利用反射获取成员方法
public class Demo4 {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {//获取class对象Class<?> clazz = Class.forName("Reflection.Demo4.Student");//获取所有公共的方法(包括父类中的公共方法)
// Method[] methods = clazz.getMethods();
// for (Method method : methods) {
// System.out.println(method);
// }、//获取所有方法包括私有的方法(不包括父类中的方法
// Method[] methods = clazz.getDeclaredMethods();
// for (Method method : methods) {
// System.out.println(method);
// }/*** public void Reflection.Demo4.Student.setAge(int)* public void Reflection.Demo4.Student.bbb(java.lang.String,int)* private void Reflection.Demo4.Student.aaa(java.lang.String)* public int Reflection.Demo4.Student.getAge()* public java.lang.String Reflection.Demo4.Student.getName()* public java.lang.String Reflection.Demo4.Student.toString()* public void Reflection.Demo4.Student.setName(java.lang.String)*///通过方法名和形参类型获取单个方法(有方法重载不能只靠方法名获取)Method m = clazz.getDeclaredMethod("aaa", String.class);//private void Reflection.Demo4.Student.aaa(java.lang.String)System.out.println(m);//获取各种数据//获取修饰符System.out.println(m.getModifiers());//2//获取方法的名字System.out.println(m.getName());//aaa//获取方法的形参Parameter[] parameters = m.getParameters();//java.lang.String arg0for (Parameter parameter : parameters) {System.out.println(parameter);}//获取方法的异常/*** class java.io.IOException* class java.lang.NullPointerException* class java.io.EOFException*/Class<?>[] exceptionTypes = m.getExceptionTypes();for (Class<?> exceptionType : exceptionTypes) {System.out.println(exceptionType);}//方法运行/*** Method 类中用于创建对象的方法* Object invoke(Object obj,Object...args):运行方法* 参数一:用Obj对象调用该方法* 参数二:调用方法传递的参数(如果没有就不写)* 返回值:方法的返回值(如果没有就不写)*/Student s = new Student();//暴露反射m.setAccessible(true);String str = (String) m.invoke(s, "汉堡包");//aaa汉堡包System.out.println(str);//请问请问}
}
public class Student {private String name;private int age;private String aaa(String name) throws IOException,NullPointerException, EOFException {System.out.println("aaa"+name);return "请问请问";}public void bbb(String name,int age){System.out.println("bbb"+name+age);}public Student() {}public Student(String name, int age) {this.name = name;this.age = age;}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}/*** 获取* @return age*/public int getAge() {return age;}/*** 设置* @param age*/public void setAge(int age) {this.age = age;}public String toString() {return "Student{name = " + name + ", age = " + age + "}";}
}
练习
练习一
public class Test {public static void main(String[] args) throws IOException, IllegalAccessException {Student s = new Student("小A",23,'女',167.5,"睡觉");Teacher t = new Teacher("波妞",10000);setdata(s);
// setdata(t);}public static void setdata(Object obj) throws IOException, IllegalAccessException {//获取输出流FileOutputStream fos = new FileOutputStream("javaseday35\\src\\main\\java\\Reflection\\Test\\Test1\\a.txt");OutputStreamWriter osw = new OutputStreamWriter(fos);BufferedWriter bw = new BufferedWriter(osw);//获取输入对象的类对象Class<?> clazz = obj.getClass();//获取成员对象Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {
// //处理成员对象,将成员对象转化为String类型
// String string = field.toString();
// //将对象的名字使用split方法进行切割,使用转义字符按照 . 进行切割
// String[] split = string.split("\\.");
// //将最后赋值给key
// String key = split[split.length - 1];String key = field.getName();
// System.out.println(string1);//处理每个成员对象//授权访问私有对象field.setAccessible(true);//获取到对用的值Object o = field.get(obj);String value = o.toString();//将key和value 存入文件bw.write(key+"="+value);bw.newLine();bw.flush();}bw.close();}
}
public class Student {private String name;private int age;private char gender;private double height;private String hobby;
public class Teacher {private String name;private double salary;
name=波妞
salary=10000.0l
练习二
public class Test {public static void main(String[] args) throws IOException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException {//获取配置文件的信息Properties pro = new Properties();FileInputStream fis = new FileInputStream("javaseday35\\src\\main\\java\\Reflection\\Test\\Test2\\pro.properties");//读取配置文件的信息pro.load(fis);fis.close();System.out.println(pro);//获取全类名和方法名String classmane = (String) pro.get("classmane");String mothed = (String) pro.get("mothed");System.out.println(classmane);System.out.println(mothed);//通过反射获取信息Class<?> clazz = Class.forName(classmane);//获取空参构造Constructor<?> constructor = clazz.getDeclaredConstructor();//通过空参构造获取空参对象Object o = constructor.newInstance();//通过方法名获取方法Method method = clazz.getDeclaredMethod(mothed);//调用方法method.invoke(o);}}
pro.propertiesclassmane=Reflection.Test.Test2.Student
mothed=eat
public class Student {private String name;private int age;private char gender;private double height;private String hobby;public void eat(){System.out.println("正在吃饭");}
public class Teacher {private String name;private double salary;public void eat(){System.out.println("正在吃饭");}
总结
动态代理
public class BigStar implements Star{private String name;public String sing(String name){System.out.println(this.name+"正在唱"+name);return "谢谢";}public void drice(){System.out.println(name+"正在跳舞");}public BigStar() {}public BigStar(String name) {this.name = name;}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}public String toString() {return "BigStar{name = " + name + "}";}
}
public interface Star {public abstract String sing(String name);public abstract void drice();
}
小结
创建代理
/*
*
* 类的作用:
* 创建一个代理
*
* */
public class ProxyUtil {/*** 方法的作用:* 给一个明星的对象,创建一个代理** 形参:* 被代理的明星对象** 返回值:* 给明星创建的代理**** 需求:* 外面的人想要大明星唱一首歌* 1. 获取代理的对象* 代理对象 = ProxyUtil.createProxy(大明星的对象);* 2. 再调用代理的唱歌方法* 代理对象.唱歌的方法("只因你太美");* */public static Star createProxy(BigStar bigStar){/* java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法:public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)参数一:用于指定用哪个类加载器,去加载生成的代理类参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法参数三:用来指定生成的代理对象要干什么事情*/Star star = (Star) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),//参数一:用于指定用哪个类加载器,去加载生成的代理类new Class[]{Star.class},//参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法//参数三:用来指定生成的代理对象要干什么事情new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {/** 参数一:代理的对象* 参数二:要运行的方法 sing* 参数三:调用sing方法时,传递的实参* */if("sing".equals(method.getName())){System.out.println("准备话筒,收钱");}else if("dance".equals(method.getName())){System.out.println("准备场地,收钱");}//去找大明星开始唱歌或者跳舞//代码的表现形式:调用大明星里面唱歌或者跳舞的方法return method.invoke(bigStar,args);}});return star;}
}
public class Test {public static void main(String[] args) {/*需求:外面的人想要大明星唱一首歌1. 获取代理的对象代理对象 = ProxyUtil.createProxy(大明星的对象);2. 再调用代理的唱歌方法代理对象.唱歌的方法("只因你太美");*///1. 获取代理的对象BigStar bigStar = new BigStar("鸡哥");Star proxy = ProxyUtil.createProxy(bigStar);//2. 调用唱歌的方法String result = proxy.sing("只因你太美");System.out.println(result);}
}
public class BigStar implements Star {private String name;public BigStar() {}public BigStar(String name) {this.name = name;}//唱歌@Overridepublic String sing(String name){System.out.println(this.name + "正在唱" + name);return "谢谢";}//跳舞@Overridepublic void dance(){System.out.println(this.name + "正在跳舞");}/*** 获取* @return name*/public String getName() {return name;}/*** 设置* @param name*/public void setName(String name) {this.name = name;}public String toString() {return "BigStar{name = " + name + "}";}
}
public interface Star {//我们可以把所有想要被代理的方法定义在接口当中//唱歌public abstract String sing(String name);//跳舞public abstract void dance();}