Java 反射 新手入门,含详细代码示例
1、反射的基本概念
可以通过反射得到类中的所有内容:
1)属性
2)无参构造方法
3)有参构造方法
4)普通方法
然后说一下到哪一步可以使用反射?
1)首先我们会创建一个java文件:.java文件
2)然后会对该java文件进行编译:.class文件
3)此时使用jvm将class文件通过类加载加载到内存中。
这个时候,我们一开始创建的所有java类在内存里面就可以以Class类存在,通过这个Class类就可以得到类中的所有内容。
1)封装了属性的类使用:Field
2)封装了构造方法的类使用:Constructor
3)封装了普通方法的类使用:Method
2、使用反射操作无参构造方法
假如我们创建一个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 0
3、使用反射操作有参构造方法
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 0
4、使用反射操作类的属性
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 0
5、使用反射操作类的普通方法
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

本文详细介绍了Java反射的基础概念,包括无参和有参构造方法的操作,类属性及普通方法的使用。通过实例演示如何利用反射创建对象、设置属性和调用方法。
643

被折叠的 条评论
为什么被折叠?



