【Java】反射机制介绍与Class类的基本能使用(工厂模式)

Noella ·
更新时间:2024-11-14
· 930 次阅读

Java反射机制与Class类1.Java反射机制1.1 反射机制是什么1.2 反射的应用场合1.3 反射的常用类1.4 反射使用步骤2. Class类2.1 常用方法和示例2.2 获取Class对象的 3 种方法2.3 反射创建对象的 2 种方法3. 工厂设计模式(示例) 1.Java反射机制 1.1 反射机制是什么

在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能为Java语言的反射机制。

1.2 反射的应用场合

程序在运行时可能接受到外部传入的对象,该对象的编译时类型为Object,但是程序有需要改对象的运行时类型的方法。
为了解决这些问题,程序需要在运行时发现对象和类的真实信息。
如果编译时根本无法预知该对象和类属于哪些类,比如这些类都是以字符串形式存放在配置文件中的时候,程序只能依靠运行时信息来发现该对象和类的真实信息,此时必须使用反射了。

1.3 反射的常用类 Class类(模板类):java.lang.Class 反射的核心类,可以获取类的属性、方法等信息; Field类:java.lang.reflec包中的类,表示类的成员变量,可以用来获取和设置类之中的属性值; Method类:Java.lang.reflec包中的类,表示类的方法,它可以用来获取类中的方法信息或者执行方法; Constructor类:Java.lang.reflec包中的类,表示类的构造方法。 1.4 反射使用步骤

获取想要操作的类的Class对象,他是反射的核心,通过Class对象我们可以任意调用类的方法;
调用Class类中的方法,即就是反射的使用阶段;
使用反射API来操作这些信息。

类的对象:基于某个类new出来的对象,也称为实例对象。 类对象:类加载的产物,封装了一个类的所有信息
————类名、父类、接口、属性、方法、构造方法 2. Class类

位置:java.lang.Class

类对象,类的实例代表一个运行 类 java应用程序的类和接口。 public final class Class extends Object implements Serializable, GenericDeclaration, Type, AnnotatedElement 2.1 常用方法和示例

常用方法:

String getName() 返回由 类对象表示的实体(类,接口,数组类,原始类型或空白)的名称,作为 String 。 static Class forName(String className) 获取类对象名 Package getPackage() 获取类对象的包名 Class getSuperclass() 获取父类的类对象名 Class[] getInterfaces() 获取接口的类对象名 Constructor[] getConstructors() 获取构造方法 Class[] getParameterTypes() 获取方法(构造/成员)的参数类型列表 Field[] getFields() 获取属性(自身+父类的所有public公开属性) Field[] getDeclaredFields() 获取属性(自身所有的属性) Method[] getMethods() 获取方法(自身+父类单继承叠加的所有public公开方法) Method[] getDeclaredMethods() 获取方法(自身所有的方法) T newInstance() 创建由此类对象表示的类的新实例(此类对象必须有无参构造)。

方法使用示例:

public class TestClassMethods { public static void main(String[] args) throws Exception { // 获取类对象 Class c = Class.forName("com.day.methods.Student"); System.out.println(c.getName()); // com.day.methods.Student // 获得指定类对象的包名 Package pack = c.getPackage(); System.out.println(pack.getName()); // com.day.methods // 获得父类的类对象 Class superClass = c.getSuperclass(); System.out.println(superClass.getName()); // com.day.methods.Person // 获得接口的类对象 Class[] interfaces = c.getInterfaces(); for (Class inter : interfaces) { // java.io.Serializable java.lang.Runnable java.lang.Comparable System.out.print(inter.getName() + " "); } // 获取属性(自身+父类的public公开属性) Field[] fields = c.getFields(); for (Field field : fields) { System.out.print(field.getName() + " "); // name age name money } // 获取属性(自身所有的属性) Field[] fields2 = c.getDeclaredFields(); for (Field field : fields2) { System.out.print(field.getName() + " "); // name age score } System.out.println("\n---------------------"); // 获取方法(自身+父类单继承叠加的所有public公开方法) Method[] methods = c.getMethods(); for (Method method : methods) { // run compareTo exam play sleep eat wait wait wait equals toString hashCode getClass notify notifyAll System.out.print(method.getName() + " "); } System.out.println("\n---------------------"); // 获取方法(自身所有的方法) Method[] methods2 = c.getDeclaredMethods(); for (Method method : methods2) { // run:void compareTo:int play:void exam:void System.out.println(method.getName() + ":" + method.getReturnType()); } System.out.println("*************************"); // 获取构造方法 Constructor[] cs = c.getConstructors(); for (Constructor cc : cs) { // com.day.methods.Student:java.lang.String int // com.day.methods.Student:java.lang.String // com.day.methods.Student: (无参构造) System.out.print(cc.getName() + ":"); Class[] param = cc.getParameterTypes(); for (Class p : param) { System.out.print(p.getName() + " "); } System.out.println(); } System.out.println(); // new一个实例对象(必须要有无参构造) Object o = c.newInstance(); Student stu = (Student)o; System.out.println(stu); // com.day.methods.Student@3d4eac69 } } class Person { public String name; public double money; public Person() {} public void eat() {} public void sleep() {} } @SuppressWarnings({ "serial", "rawtypes" }) class Student extends Person implements Serializable, Runnable, Comparable{ public String name; public int age; double score; public Student() {super();} public Student(String name) {} public Student(String name, int age) {} public void exam() {} public void play() {} @Override public void run() {} @Override public int compareTo(Object o) { return 0; } } 2.2 获取Class对象的 3 种方法

① 通过类的对象,获取Class对象
② 通过类名获取一个Class对象
通过Class的静态方法forName()获取类对象 【最具普适性】

public class TestGetClassObject { public static void main(String[] args) throws ClassNotFoundException { // 1.通过类的对象,获取Class对象 Person p = new Person(); // 类的对象 Class c = p.getClass(); System.out.println(c.getName()); // 2.通过类名获取一个Class对象 Class c2 = Person.class; System.out.println(c2.getName()); // 3.通过Class的静态方法获取类对象 【最具普适性】 Class c3 = Class.forName("com.day.reflect.Person"); System.out.println(c3.getName()); } // 更通用的获取类对象的方法 public static Class getClassObject(String className) { Class c = null; try { c = Class.forName(className); } catch (ClassNotFoundException e) { e.printStackTrace(); } return c; } } class Person { } 2.3 反射创建对象的 2 种方法

① 反射通过类对象创建类的对象
方法传参返回对象【普适性】

public class TestNewInstance { public static void main(String[] args) throws Exception { // 手工new对象 Teacher t = new Teacher(); t.name = "JJ"; System.out.println(t.name); // 1.反射通过类对象创建类的对象 Class c = Class.forName("com.day.methods.Teacher"); Teacher t2 = (Teacher)c.newInstance(); t2.name = "Jerry"; System.out.println(t2.name); // 2.方法传参返回对象【普适性】 Teacher t3 = (Teacher)createObject("com.day.methods.Teacher"); System.out.println(t3); } public static Object createObject(String className) { try { Class c = Class.forName(className); return c.newInstance(); } catch (Exception e) { e.printStackTrace(); } return null; } } class Teacher { String name; public Teacher() { } } 3. 工厂设计模式(示例) 开发中有一个非常重要的原则“开闭原则”,对拓展开放、对修改关闭; 工厂模式主要负责对象创建的问题; 可通过反射进行工厂模式的设计,完成动态的对象创建public class TestNewInstanceForFile { public static void main(String[] args) throws Exception { // 创建出入流对象 FileReader fr = new FileReader("files\\application.txt"); BufferedReader br = new BufferedReader(fr); // 读出文件中的类的全限定名 String className = br.readLine(); // 创建Object对象返回后进行强转为对应类型,进而使用 Teacher t3 = (Teacher)createObject(className); System.out.println(t3); br.close(); } /** * 工厂:创建对象工厂 * @param className String类型的类的全限定名 * @return Object Object类型的对象 */ public static Object createObject(String className) { try { Class c = Class.forName(className); return c.newInstance(); } catch (Exception e) { e.printStackTrace(); } return null; } } /* * files\\application.txt 内容: * com.methods.Teacher */
作者:不才Jerry



JAVA class class类 反射 工厂模式 反射机制

需要 登录 后方可回复, 如果你还没有账号请 注册新账号