您的位置:首页 > 汽车 > 新车 > 镇江制作网页图片_网页设计证书考什么_网站维护收费标准_站长统计免费下载

镇江制作网页图片_网页设计证书考什么_网站维护收费标准_站长统计免费下载

2024/11/15 11:22:27 来源:https://blog.csdn.net/fulai00/article/details/143568434  浏览:    关键词:镇江制作网页图片_网页设计证书考什么_网站维护收费标准_站长统计免费下载
镇江制作网页图片_网页设计证书考什么_网站维护收费标准_站长统计免费下载

目录

  1. 先看个例子
  2. 基本概念
  3. Class 2.1 获取Class 2.2 通过Class获取类修饰符和类型
  4. Member 3.1 Field 3.1.1 获取Field 3.1.2 获取变量类型、修饰符、注解 3.1.3 获取、设置变量值 3.2 Method 3.2.1 获取Method 3.2.2 获取方法返回类型 3.2.3 获取方法参数类型 3.2.4 获取方法声明抛出的异常类型 3.2.5 获取方法参数名称 3.2.6 通过反射调用方法 3.3 Constructor 3.3.1 获取构造方法 3.3.2 创建对象
  5. 数组和枚举 4.1 数组 4.2 枚举
  6. 反射的缺点 参考

1. 先看个例子

public class People {private People(int age) {}public void show() {System.out.println("test reflect");}
}//test code
Class<?> clazz = Class.forName("com.xfhy.ref.People");
Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(int.class);
declaredConstructor.setAccessible(true);
People person = (People) declaredConstructor.newInstance(12);
person.show();
通过这个简单的例子,我们可以看到Java反射的强大之处:即使People的构造方法是私有的,我们仍然可以通过反射机制来创建其实例。

2. 基本概念

Java的反射机制能够:

  • 对于任意一个类,都能够知道这个类的所有属性和方法。
  • 对于任意一个对象,都能够调用它的任意一个方法和属性。

这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。反射机制主要涉及两个类:ClassMember

3. Class

Class是反射能够实现的基础,Class是JDK提供的一个类,完整路径是java.lang.Class。本质上这个类和MathString或者自己定义的各种类没有区别。

3.1 获取Class

获取Class对象的几种方法:

  • Object.getClass():对象实例调用getClass方法。
  • The.class:类调用.class,例如String.class
  • Class.forName(""):传入类的全路径。
  • The.TYPE:例如Double.TYPE
  • Class.getSuperclass():某个实例调用getClass().getSuperclass()

3.2 通过Class获取类修饰符和类型

HashMap为例,我们可以通过反射获取类的修饰符、泛型信息、实现的接口、父类和注解等信息。

Class<?> clazz = HashMap.class;
System.out.println("Class : " + clazz.getCanonicalName());
System.out.println(Modifier.toString(clazz.getModifiers()));
TypeVariable<? extends Class<?>>[] typeParameters = clazz.getTypeParameters();
StringBuilder stringBuilder = new StringBuilder("Parameters : ");
for (TypeVariable<? extends Class<?>> typeParameter : typeParameters) {stringBuilder.append(typeParameter.getName()).append(" ");
}
System.out.println(stringBuilder.toString());Type[] genericInterfaces = clazz.getGenericInterfaces();
StringBuilder interfaces = new StringBuilder("Implemented Interfaces : ");
for (Type intf : genericInterfaces) {interfaces.append(intf.toString()).append(" ");
}
System.out.println(interfaces.toString());Class<?> superclass = clazz.getSuperclass();
if (superclass != null) {System.out.println(superclass.getCanonicalName());
}Annotation[] annotations = clazz.getAnnotations();
StringBuilder annotation = new StringBuilder("Annotations : ");
for (Annotation a : annotations) {annotation.append(a.toString()).append(" ");
}
System.out.println(annotation.toString());

4. Member

Member有三个实现类:

  • java.lang.reflect.Field:类变量
  • java.lang.reflect.Method:类方法
  • java.lang.reflect.Constructor:类构造方法

4.1 Field

通过Field可以访问给定类对象的类变量,包括获取变量的类型、修饰符、注解、变量名、变量值等,即使是private的也是OK的。

4.1.1 获取Field

Class提供了四种方法获得给定类的Field

  • getDeclaredField(String name):获取指定的变量,包括private的。
  • getField(String name):获取指定的变量,只能是public的。
  • getDeclaredFields():获取所有变量,包括private的。
  • getFields():获取所有变量,只能是public的。
4.1.2 获取变量类型、修饰符、注解
Class clazz = People.class;
Field[] declaredFields = clazz.getDeclaredFields();
for (Field field : declaredFields) {StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("变量名: ").append(field.getName()).append("\n");stringBuilder.append("变量类型: ").append(field.getType()).append("\n");stringBuilder.append("变量修饰符: ").append(Modifier.toString(field.getModifiers())).append("\n");Annotation[] annotations = field.getAnnotations();if (annotations.length != 0) {stringBuilder.append(" 变量注解 : ");for (Annotation a : annotations) {stringBuilder.append(a.toString()).append(" ");}}System.out.println(stringBuilder.toString());
}
4.1.3 获取、设置变量值
People people = new People("张三", 17);
Class<? extends People> peopleClass = people.getClass();
try {Field nameField = peopleClass.getDeclaredField("name");nameField.setAccessible(true);Field ageField = peopleClass.getField("age");String name = (String) nameField.get(people);int age = ageField.getInt(people);System.out.println("name = " + name + ", age = " + age);nameField.set(people, "李四");ageField.set(people, 18);System.out.println(people.toString());
} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();
}

4.2 Method

4.2.1 获取Method

Class提供了四种方法获取Method

  • getDeclaredMethod(String name, Class<?>... parameterTypes)
  • getMethod(String name, Class<?>... parameterTypes)
  • getDeclaredMethods()
  • getMethods()
4.2.2 获取方法返回类型
  • getReturnType():获取目标方法返回类型对应的Class对象。
  • getGenericReturnType():获取目标方法返回类型对应的Type对象。
4.2.3 获取方法参数类型
  • getParameterTypes():获取目标方法各参数类型对应的Class对象。
  • getGenericParameterTypes():获取目标方法各参数类型对应的Type对象。
4.2.4 获取方法声明抛出的异常类型
  • getExceptionTypes():获取目标方法抛出的异常类型对应的Class对象。
  • getGenericExceptionTypes():获取目标方法抛出的异常类型对应的Type对象。
4.2.5 获取方法参数名称

.class文件中默认不存储方法参数名称,如果想要获取方法参数名称,需要在编译的时候加上-parameters参数。

4.2.6 通过反射调用方法

通过Methodinvoke()方法来反射调用目标方法,第一个参数为需要调用的目标类对象。如果方法是static的,则该参数为null,后面的参数是目标方法的参数值,顺序与目标方法声明中的参数顺序一致。

4.3 Constructor

4.3.1 获取构造方法

Method类似。

4.3.2 创建对象

一般使用java.lang.reflect.Constructor.newInstance()来构建对象,另一种Class.newInstance()已经废弃。

5. 数组和枚举

5.1 数组

数组类型:数组本质上是一个对象,所以它也有自己的类型。例如对于int[] intArray,数组类型为class [I。数组类中的[个数代表数组的维度,例如[代表一维数组,[[代表二维数组,[后面的字母代表数组元素类型,I代表int,一般为类型的首字母大写(long类型例外,为J)。

创建和初始化数组:

Object array = Array.newInstance(int.class, 2);
Array.set(array, 0, 1);
Array.set(array, 1, 2);
System.out.println(Array.get(array, 1));

多维数组:Java反射没有提供能够直接访问多维数组元素的API,但你可以把多维数组当成数组的数组处理。

5.2 枚举

枚举隐式继承自java.lang.EnumEnum继承自Object

结论

Java反射机制是Java语言的一个重要特性,它提供了一种动态访问和操作对象的能力。虽然它有性能和安全上的考量,但在需要动态性和灵活性的场景下,反射是一个不可或缺的工具。理解和掌握反射机制,可以帮助我们编写出更加灵活和强大的Java程序。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com