- 1、反射的基本概念
- 2、使用反射 *** 作无参构造方法
- 3、使用反射 *** 作有参构造方法
- 4、使用反射 *** 作类的属性
- 5、使用反射 *** 作类的普通方法
可以通过反射得到类中的所有内容:
1)属性
2)无参构造方法
3)有参构造方法
4)普通方法
然后说一下到哪一步可以使用反射?
1)首先我们会创建一个java文件:.java文件
2)然后会对该java文件进行编译:.class文件
3)此时使用jvm将class文件通过类加载加载到内存中。
这个时候,我们一开始创建的所有java类在内存里面就可以以Class类存在,通过这个Class类就可以得到类中的所有内容。
1)封装了属性的类使用:Field
2)封装了构造方法的类使用:Constructor
3)封装了普通方法的类使用:Method
假如我们创建一个Person的类,首先要知道获取类的3种方式:
1)Class c1 = Person.class;
2)Class c2 = new Person().getCLass();
3)Class c3 = Class.forName();
其次,构造新对象现在除了使用new关键词之后,现在还可以使用Class类的newInstance方法来新建对象。
Person p = (Person) c3.newInstance();
使用无参构造方法的代码示例如下:
1)首先创建一个Person类
package com.seleflearn; public class Person { // 2个属性 private String name; private int age; // 无参构造函数 public Person() {}; // 有参构造函数 public Person(String name, int age) { this.name = name; this.age = age; } // 普通方法 @Override public String toString() { return this.name + "的年龄是:" + this.age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public int getAge() { return age; } }
2)然后通过反射创建实例,并给实例设置属性值
package com.seleflearn; public class test1 { public static void main(String[] args) throws Exception{ // 得到Class Class c = Class.forName("com.seleflearn.Person"); // 使用无参构造方法创建Person的实例 Person p = (Person) c.newInstance(); // 设置名称和年龄 p.setName("张三"); p.setAge(20); System.out.println(p.toString()); } }
运行结果如下:
/opt/java/jdk-16.0.2/bin/java -javaagent:/opt/idea-IC-212.5457.46/lib/idea_rt.jar=45811:/opt/idea-IC-212.5457.46/bin -Dfile.encoding=UTF-8 -classpath /home/koping/wxp/learn/java/java-web/day20211017/out/production/testReflection com.seleflearn.test4 张三的年龄是:20 Process finished with exit code 03、使用反射 *** 作有参构造方法
1)通过getConstructors()方法获取所有的构造方法:
c.getConstructors();
2)通过getConstructor()方法获取有参数构造方法,获取有参构造方法的参数类型,需要使用class形式传递
Constructor cs = c.getConstructor(String.class, int.class);
3)通过有参构造方法可以创建实例:
Person p = (Person) cs.newInstance(“张三”, 20);
使用有残构造方法创建并设置实例的示例如下:
package com.seleflearn; import java.lang.reflect.Constructor; public class test2 { public static void main(String[] args) throws Exception{ // 得到Class Class c = Class.forName("com.seleflearn.Person"); // 获取有参数构造方法,获取有参构造方法的参数类型,需要使用class形式传递 Constructor cs = c.getConstructor(String.class, int.class); // 通过有参构造方法创建Person的实例 Person p = (Person) cs.newInstance("张三", 20); System.out.println(p.toString()); } }
运行结果如下:
/opt/java/jdk-16.0.2/bin/java -javaagent:/opt/idea-IC-212.5457.46/lib/idea_rt.jar=35505:/opt/idea-IC-212.5457.46/bin -Dfile.encoding=UTF-8 -classpath /home/koping/wxp/learn/java/java-web/day20211017/out/production/testReflection com.seleflearn.test2 张三的年龄是:20 Process finished with exit code 04、使用反射 *** 作类的属性
1)通过getDeclaredFields()方法得到类的所有属性
c.getDeclaredFields();
2)通过getDeclaredField()方法得到类的属性,该方法的参数是该属性的名称
Field fieldName = c.getDeclaredField(“name”);
Field fieldAge = c.getDeclaredField(“age”);
3)当 *** 作的是私有属性的时候,需要设置可 *** 作权限为true才使用
fieldName.setAccessible(true);
fieldAge.setAccessible(true);
4)给所创建的实例设置属性,有2个参数:第1个参数是类的实例,第2个参数是所需要设置的值
fieldName.set(p, “张三”);
fieldAge.set(p, 20);
使用类的属性来设置实例的示例代码如下:
package com.seleflearn; import java.lang.reflect.Constructor; import java.lang.reflect.Field; public class test3 { public static void main(String[] args) throws Exception{ // 得到Class Class c = Class.forName("com.seleflearn.Person"); // 使用无参构造方法创建Person的实例 Person p = (Person) c.newInstance(); // 得到name和age属性 Field fieldName = c.getDeclaredField("name"); Field fieldAge = c.getDeclaredField("age"); // 当 *** 作的是私有属性的时候,需要设置可 *** 作权限为true才使用 fieldName.setAccessible(true); fieldAge.setAccessible(true); // 给所创建的实例设置属性,有2个参数:第1个参数是类的实例,第2个参数是所需要设置的值 fieldName.set(p, "张三"); fieldAge.set(p, 20); System.out.println(p.toString()); } }
运行结果如下:
/opt/java/jdk-16.0.2/bin/java -javaagent:/opt/idea-IC-212.5457.46/lib/idea_rt.jar=46023:/opt/idea-IC-212.5457.46/bin -Dfile.encoding=UTF-8 -classpath /home/koping/wxp/learn/java/java-web/day20211017/out/production/testReflection com.seleflearn.test3 张三的年龄是:20 Process finished with exit code 05、使用反射 *** 作类的普通方法
1)通过getDeclaredMethods()来得到所有普通方法
c.getDeclaredMethods()
2)通过getDeclaredMethod()得到指定的普通方法,得到指定的普通方法需要传递2个参数:第1个参数是方法名称,第2个参数是参数类型
Method setName = c.getDeclaredMethod(“setName”, String.class);
Method setAge = c.getDeclaredMethod(“setAge”, int.class);
3)得到普通方法后,使用invoke进行调用,调用invoke需要传递2个参数:第1个参数是该类的实例,第2个参数是该方法所需的参数值
setName.invoke(p, “张三”);
setAge.invoke(p, 20);
4)如果 *** 作的是私有方法,那么也需要先设置 *** 作权限为true
setName.setAccessible(true);
setAge.setAccessible(true);
5)当 *** 作的方法是静态方法时,由于静态方法的调用方式是:类名.静态方法名
所以不需要类的实例,所以将invoke方法的第一个参数设置为null即可
setName.invoke(null, “张三”);
setAge.invoke(null, 20);
使用类的普通方法来设置实例的示例代码如下:
package com.seleflearn; import java.lang.reflect.Field; import java.lang.reflect.Method; public class test4 { public static void main(String[] args) throws Exception { // 得到Class Class c = Class.forName("com.seleflearn.Person"); // 使用无参构造方法创建Person的实例 Person p = (Person) c.newInstance(); // 得到普通方法需要传递2个参数:第1个参数是方法名称,第2个参数是参数类型 Method setName = c.getDeclaredMethod("setName", String.class); Method setAge = c.getDeclaredMethod("setAge", int.class); // 得到普通方法后,使用invoke进行调用,调用invoke需要传递2个参数:第1个参数是该类的实例,第2个参数是该方法所需的参数值 setName.invoke(p, "张三"); setAge.invoke(p, 20); // 注:如果 *** 作的是私有方法,那么也需要先设置 *** 作权限为true // setName.setAccessible(true); // setAge.setAccessible(true); System.out.println(p.toString()); } }
运行结果如下:
/opt/java/jdk-16.0.2/bin/java -javaagent:/opt/idea-IC-212.5457.46/lib/idea_rt.jar=39419:/opt/idea-IC-212.5457.46/bin -Dfile.encoding=UTF-8 -classpath /home/koping/wxp/learn/java/java-web/day20211017/out/production/testReflection com.seleflearn.test4 张三的年龄是:20 Process finished with exit code 0
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)