1.什么是反射
反射是 Java 技术中一个非常重要的特性。反射为 J2EE 中的框架提供了很多灵活性,在构建大型应用程序时非常有用。在 J2EE 中,使用反射技术可以实现很多高级功能,比如动态代理、ORM 框架、AOP 以及一些安全和权限控制等。
2.类类的获取(三种方式)
2.1Class.forName(完整类名)
代码如下:
package com.Kissship; /** * 类类的获取(三种方式) * 1.Class.forName * 2.类实例.getClass * 3.类名.class * @author jj * */ public class Demo1 { public static void main(String[] args) throws Exception { Student stu = new Student(); //1.Class.forName //java.lang.Class 类类,应用在jdbc数据库链接中 Class c1 = Class.forName("com.Kissship.Student"); System.out.println(c1); } }
2.2类名.class
代码如下:
package com.Kissship; /** * 类类的获取(三种方式) * 1.Class.forName * 2.类实例.getClass * 3.类名.class * @author jj * */ public class Demo1 { public static void main(String[] args) throws Exception { Student stu = new Student(); //2.类实例.getClass //通用增删改 Class c2 = stu.getClass(); System.out.println(c2); } }
2.3对象.getClass()
代码如下:
package com.Kissship; /** * 类类的获取(三种方式) * 1.Class.forName * 2.类实例.getClass * 3.类名.class * @author jj * */ public class Demo1 { public static void main(String[] args) throws Exception { Student stu = new Student(); //3.类名.class //通用查询 Class c3 = Student.class; System.out.println(c3); } }
3.反射实例化
1.getConstructor
2.getDeclaredConstructor
3.newInstance
3.1调用无参构造器反射实例化
方法如下:
package com.Kissship; /** * 反射实例化 * 所有实体类,添加了有参构造器,一定记得补无参构造器 * @author jj * */ public class Demo2 { public static void main(String[] args) throws Exception { //一切反射从类类开始 Student stu = new Student(); // 添加了有参构造器,一定记得补无参构造器 // 1.调用无参构造器反射实例化 Class c1 = Class.forName("com.Kissship.Student"); Student s1 = (Student) c1.newInstance(); System.out.println(s1); } }
3.2调用有一个参数的构造器反射实例化
方法如下:
package com.Kissship; import java.lang.reflect.Constructor; /** * 反射实例化 * 所有实体类,添加了有参构造器,一定记得补无参构造器 * @author jj * */ public class Demo2 { public static void main(String[] args) throws Exception { //一切反射从类类开始 Student stu = new Student(); // 添加了有参构造器,一定记得补无参构造器 // 1.调用无参构造器反射实例化 Class c1 = Class.forName("com.Kissship.Student"); Student s1 = (Student) c1.newInstance(); System.out.println(s1); // 2.调用有一个参数的构造器反射实例化 //parameterTypes:代表了参数的类别 Constructor cr1 = c1.getConstructor(String.class); Object s2 = cr1.newInstance("come1"); System.out.println(s2); } }
3.3调用有两个参数的构造器反射实例化
方法如下:
package com.Kissship; import java.lang.reflect.Constructor; /** * 反射实例化 * 所有实体类,添加了有参构造器,一定记得补无参构造器 * @author jj * */ public class Demo2 { public static void main(String[] args) throws Exception { //一切反射从类类开始 Student stu = new Student(); // 添加了有参构造器,一定记得补无参构造器 // 1.调用无参构造器反射实例化 Class c1 = Class.forName("com.Kissship.Student"); Student s1 = (Student) c1.newInstance(); System.out.println(s1); // 2.调用有一个参数的构造器反射实例化 //parameterTypes:代表了参数的类别 Constructor cr1 = c1.getConstructor(String.class); Student s2 = (Student) cr1.newInstance("come1"); System.out.println(s2); // 3.调用有两个参数的构造器反射实例化 Constructor cr2 = c1.getConstructor(String.class, String.class); Student s3 = (Student) cr2.newInstance("come2","阿努比斯军团"); System.out.println(s3); } }
3.4调用私有的带有一个参数的有参构造器实例化
方法如下:
package com.Kissship; import java.lang.reflect.Constructor; /** * 反射实例化 * 所有实体类,添加了有参构造器,一定记得补无参构造器 * @author jj * */ public class Demo2 { public static void main(String[] args) throws Exception { //一切反射从类类开始 Student stu = new Student(); // 添加了有参构造器,一定记得补无参构造器 // 1.调用无参构造器反射实例化 Class c1 = Class.forName("com.Kissship.Student"); Student s1 = (Student) c1.newInstance(); System.out.println(s1); // 2.调用有一个参数的构造器反射实例化 //parameterTypes:代表了参数的类别 Constructor cr1 = c1.getConstructor(String.class); Student s2 = (Student) cr1.newInstance("come1"); System.out.println(s2); // 3.调用有两个参数的构造器反射实例化 Constructor cr2 = c1.getConstructor(String.class, String.class); Student s3 = (Student) cr2.newInstance("come2","阿努比斯军团"); System.out.println(s3); // 4.调用私有的带有一个参数的有参构造器实例化 //getConstructor方法只能获取到公有的构造器对象 Constructor cr3 = c1.getDeclaredConstructor(Integer.class); cr3.setAccessible(true);//打开权限 Student s4 = (Student) cr3.newInstance(18);//私有构造器不能直接反射实例化,没有权限 } }
这里需要注意的是:在获取私有构造器时要用getDeclaredConstructor方法,另外在反射实例化之前我们需要打开权限才能反射实例化,否则的话就无权反射。
控制台输出结果如下:
4.反射动态方法调用
1.getMethod 2.getDeclaredMethod
4.1反射调用无参方法
方法如下:
package com.Kissship; import java.lang.reflect.Method; /** * 反射动态方法调用 * * @author jj * */ public class Demo3 { public static void main(String[] args) throws Exception { Class c = Student.class; Student stu = (Student) c.newInstance();// 获取方法对象 // 1.反射调用无参方法,先获取到方法对象 // name:方法名 parameterTypes:调用这个方法要传的参数类型------.getMethod(name, parameterTypes); Method m1 = c.getMethod("hello");// 此处是无参方法,所以parameterTypes处不传 // obj:类实例 args:参数值----.invoke(obj, args); // invoke:方法的返回值 Object invoke = m1.invoke(stu);// 无参,参数值无需传 System.out.println(invoke); } }
控制台输出结果如下:
4.2反射调用有参方法
方法如下:
package com.Kissship; import java.lang.reflect.Method; /** * 反射动态方法调用 * * @author jj * */ public class Demo3 { public static void main(String[] args) throws Exception { Class c = Student.class; Student stu = (Student) c.newInstance();// 获取方法对象 // 1.反射调用无参方法,先获取到方法对象 // name:方法名 parameterTypes:调用这个方法要传的参数类型------.getMethod(name, parameterTypes); Method m1 = c.getMethod("hello");// 此处是无参方法,所以parameterTypes处不传 // obj:类实例 args:参数值----.invoke(obj, args); // invoke:方法的返回值 Object invoke = m1.invoke(stu);// 无参,参数值无需传 System.out.println(invoke); // 2.反射调用有参方法 Method m2 = c.getMethod("hello", String.class); Object invoke2 = m2.invoke(stu, "二西莫夫"); System.out.println(invoke2); } }
控制台输出结果如下:
4.3反射调用私有的有参方法
方法如下:
package com.Kissship; import java.lang.reflect.Method; /** * 反射动态方法调用 * * @author jj * */ public class Demo3 { public static void main(String[] args) throws Exception { Class c = Student.class; Student stu = (Student) c.newInstance();// 获取方法对象 // 1.反射调用无参方法,先获取到方法对象 // name:方法名 parameterTypes:调用这个方法要传的参数类型------.getMethod(name, parameterTypes); Method m1 = c.getMethod("hello");// 此处是无参方法,所以parameterTypes处不传 // obj:类实例 args:参数值----.invoke(obj, args); // invoke:方法的返回值 Object invoke = m1.invoke(stu);// 无参,参数值无需传 System.out.println(invoke); // 2.反射调用有参方法 Method m2 = c.getMethod("hello", String.class); Object invoke2 = m2.invoke(stu, "二西莫夫"); System.out.println(invoke2); // 3.反射调用私有的有参方法 Method m3 = c.getDeclaredMethod("add",Integer.class,Integer.class); m3.setAccessible(true);//打开权限 Object invoke3 = m3.invoke(stu, 999,998); System.out.println(invoke3); } }
控制台输出结果如下:
在调用私有的方法时,也需要打开权限才能得到权限。否则控制台输出会报错。
5.反射读写属性
1.getDeclareField 2.getDeclareFields
方法如下:
package com.Kissship; import java.lang.reflect.Field; /** * 反射读写属性 * @author jj * */ public class Demo4 { public static void main(String[] args) throws Exception{ Class clz = Student.class; Student stu = new Student("come3","nia婷"); stu.age = 18; //需求: 获取到该学生stu的sid值以及sname值-->获取某一个对象中的所有属性 System.out.println(stu.getSid()); System.out.println(stu.getSname()); System.out.println("**************************"); Field snameField = clz.getDeclaredField("sname"); snameField.setAccessible(true); snameField.set(stu, "塞班"); //Field:属性对象 Field[] fields = clz.getDeclaredFields(); for (Field f : fields) { f.setAccessible(true); System.out.println(f.getName()+":"+f.get(stu)); } } }
控制台输出结果如下:
最后J2EE基础之反射就到这里,祝大家在敲代码的路上一路通畅!