a做爰视频免费网站程序员做项目的网站
- 作者: 多梦笔记
- 时间: 2026年02月16日 04:20
当前位置: 首页 > news >正文
a做爰视频免费网站,程序员做项目的网站,深圳百度seo哪家好,网站制作郑州网站制作来学习一下Java的反射#xff0c;通过Class实例获取class信息的方法称为反射#xff08;Reflection#xff09;#xff0c;内容如下
一、反射机制
1、概述
在运行状态中#xff0c;对于任意一个类#xff0c;都能够知道这个类的所有属性和方法#xff1b;对于任意一…来学习一下Java的反射通过Class实例获取class信息的方法称为反射Reflection内容如下
一、反射机制
1、概述
在运行状态中对于任意一个类都能够知道这个类的所有属性和方法对于任意一个对象都能够调用它的任意方法和属性这种动态获取信息以及动态调用对象方法的功能称为 Java 语言的反射机制。 简单来说反射机制指的是程序在运行时能够获取自身的信息。 在 Java 中只要给定类的名字就可以通过反射机制来获得类的所有信息。 2、应用举例
应用1在服务器端往往需要根据客户的请求动态调用某一个对象的特定方法。 应用2在 ORM 中间件的实现中运用 Java 反射机制可以读取任意一个 JavaBean 的所有属性或者给这些属性赋值。 反射就像是我们正常思维的一个逆过程如下 正常方式引入包类名称—-new实例化—-实例化对象 反射方式实例化对象—-getClass()方法—-包类名称 3、功能及优缺点
3.1 功能
在运行期java.lang.reflect包 1判断任意一个对象所属的类。 2构造任意一个类的对象。 3判断任意一个类所具有的成员变量和方法。 4调用任意一个对象的方法。 5生成动态代理。
3.2 优缺点
1优点 能够运行时动态获取类的实例大大提高系统的灵活性和扩展性。 与 Java 动态编译相结合可以实现非常强大的功能。 对于 Java 这种先编译再运行的语言能够很方便的创建灵活的代码可以在运行时装配无需在组件之间进行源代码的链接更加容易实现面向对象 2缺点 反射会消耗一定的系统资源如果不需要动态地创建一个对象就不需要用反射 反射调用方法时可以忽略权限检查获取类的私有方法和属性可能会破坏类的封装性而导致安全问题。 4、时期
先来看一下完整的Java程序运行过程
┌──────────────────┐
│ Hello.java │─── source code(源码)
└──────────────────┘│ compile(运行前由javac编译器编译)▼
┌──────────────────┐
│ Hello.class │─── byte code(字节码)
└──────────────────┘│ execute(运行时由java即JVM解释器解释)▼
┌──────────────────┐
│ Run on JVM │ (运行在各平台虚拟机)
└──────────────────┘4.1 编译器
1编译期执行过程 源码—-编译器编译—-可执行文件如Hello.java—-Hello.class。 注编译期只是做了一些翻译功能并没有把代码放在内存中运行只是把代码当成文本进行操作比如检查错误。 4.2 运行期
1运行期执行过程 把编译后的文件.class文件交给计算机执行直到程序运行结束由JVM解释器解释 .class字节码文件运行在各平台虚拟机上。 可执行文件—-解释器解释—-在各平台虚拟机上运行。 简单而言运行期就是把在磁盘中的代码放到内存中跑起来。 5、API 所谓API就是Java自己提供的标准类库开发人员可直接使用其方法。 5.1 java.lang.Class类
1概述
是反射机制API的核心类。Class实例一种数据类型如类、接口、注解、数组、基本数据类型和void由JVM在类加载时自动创建的。
2获取Class实例 (3种方法)
类名.class通过类名的属性class获取。多用于参数的传递对象.getClass()通过实例变量的getClass()方法getClass()方法在Object类中定义着即所有对象皆有此方法。多用于对象的获取字节码的方式Class.forName(“全类名”)将字节码文件加载进内存返回Class对象。如Class.forName(“java.lang.String”)。 注全类名即包名.类名多用于配置文件将类名定义在配置文件中。读取文件加载类 3Class实例的唯一性 Class实例在JVM中是唯一的可以用比较两个Class实例。 结论同一个字节码文件*.class在一次程序运行过程中只会被加载一次不论通过哪一种方式获取的class对象都是同一个。 4Class实例比较和 instanceof的区别
instanceof不但匹配指定类型还匹配指定类型的子类。而用判断class实例可以精确地判断数据类型但不能作子类型比较。通常情况下用 instanceof判断数据类型因为面向抽象编程不关心具体的子类型。只有在需要精确判断一个类型是不是某个class的时候我们才使用判断class实例。
5示例
// java.lang包由系统自动加载无需导包
public class ClassDemo { // 反射获取Class实例public static void main(String[] args) {Class clz1 String.class; // 1.通过类型class静态变量—-(类型.class)String str Hello; //创建(实例化)字符串对象Class clz2 str.getClass(); // 2.通过对象的getClass()方法—-(对象.getClass())Class clz3 int.class; // 获得int类型Class实例Class clz4 Integer.class; // 获得Integer类型(基本类型的包装类)Class实例System.out.println(clz1.equals(clz2)); //判断两种方法获取同一类型的Class实例是否相等System.out.println(clz1类名称 clz1.getName()); //调用Class实例的方法(会用即可不用死记)System.out.println(clz2类名称 clz2.getName());System.out.println(clz2是否为接口 clz2.isInterface());System.out.println(clz2是否为数组对象 clz2.isArray());System.out.println(clz2父类名称 clz2.getSuperclass().getName());System.out.println(clz2是否为基本类型 clz2.isPrimitive());System.out.println(clz3是否为基本类型 clz3.isPrimitive());System.out.println(clz4是否为基本类型 clz4.isPrimitive());}
}运行结果
true
clz1类名称java.lang.String
clz2类名称java.lang.String
clz2是否为接口false
clz2是否为数组对象false
clz2父类名称java.lang.Object
clz2是否为基本类型false
clz3是否为基本类型true
clz4是否为基本类型false注关于基本类型的判断String为引用类型int为基本类型。Integer为基本类型的包装类是类为引用类型。 总结除基本类型外的为引用类型引用类型有三种数组、类、接口。不清楚的可以回去复习。 5.2 java.lang.reflect包
1概述
所有实现反射机制的类所在的包。reflect包的主要类 Constructor 类提供类的构造方法信息。Field 类提供类或接口中成员变量信息。Method 类提供类或接口成员方法信息。Array 类提供了动态创建和访问 Java 数组的方法。odifier 类提供类和成员访问修饰符信息。
2示例了解
import java.lang.reflect.Method; //导包
import java.lang.reflect.Modifier;public class ReflectDemo {public static void main(String[] args) {try {Class c Class.forName(java.lang.String); // 动态加载xx类的运行时对象(forName(String)方法)Method[] methods c.getDeclaredMethods(); // 获取成员方法集合for (Method method : methods) { // 遍历成员方法集合System.out.print(Modifier.toString(method.getModifiers())); // 打印权限修饰符如public、protected、privateSystem.out.print( method.getReturnType().getName() ); // 打印返回值类型名称System.out.println(method.getName() ();); // 打印方法名称}} catch (ClassNotFoundException e) {System.out.println(找不到指定类);}}
}结果比较长有兴趣的可以自己去运行一下。
二、反射访问
1、访问构造方法
1创建 Constructor 类型的对象或数组的方法
getConstructors()getConstructor(Class?…parameterTypes)getDeclaredConstructors()getDeclaredConstructor(Class?…parameterTypes)
2访问指定的构造方法需根据该构造方法入口参数的类型来访问
objectClass.getDeclaredConstructor(int.class,String.class); //访问int和String类型
objectClass.getDeclaredConstructor(new Class[]{int.class,String.class});3Constructor 类的常用方法 查看API文档了解不用死背。 isVarArgs()查看该构造方法是否允许带可变数量的参数getParameterTypes()按照声明顺序以 Class 数组的形式获取该构造方法各个参数的类型getExceptionTypes()以 Class 数组的形式获取该构造方法可能抛出的异常类型newInstance(Object … initargs)通过该构造方法利用指定参数创建一个该类型的对象如果未设置参数则表示采用默认无参的构造方法setAccessiable(boolean flag)如果该构造方法的权限为 private默认为不允许通过反射利用 netlnstance()方法创建对象。如果先执行该方法并将入口参数设置为 true则允许创建对象getModifiers()获得可以解析出该构造方法所采用修饰符的整数
4java.lang.reflect.Modifer类 Modifer英文翻译为修饰符Modifer类常用静态方法即查看是否被指定修饰符修饰。 isStatic(int mod)判断是否使用static修饰符以下同理分析isPublic(int mod)isProtected(int mod)isPrivate(int mod)isFinal(int mod)toString(int mod)以字符串形式返回所有修饰符
5示例 使用Constructor类的方法获取构造方法的信息。 5.1创建一个图书信息的Book类
public class Book { // 定义Book类String name; // 封装成员变量int id,price;public Book(){ // 无参构造方法}public Book(String name,int id){ // 带两个参数的构造方法this.namename; // this指向当前变量this.idid;}//带可变参数构造方法允许在调用方法时传入不定长度的参数//格式方法名(类型…数组名) …表示可以接受多个参数值public Book(String… strings) throws NumberFormatException{if(0strings.length) //至少有一个参数idInteger.valueOf(strings[0]); //将id转换为包装类型Integer//Integer.valueOf()方法可以将int或String转换为包装类型Integerif(1strings.length) //至少有两个参数priceInteger.valueOf(strings[1]);}// 输出图书信息public void print() {System.out.println(name name);System.out.println(id id);System.out.println(price price);}
}5.2创建测试类
import java.lang.reflect.Constructor; // 导包public class BookDemo { //测试类public static void main(String[] args) {// 获取动态类BookClass book Book.class;// 获取Book类的所有构造方法(返回一个数组)Constructor[] declaredContructors book.getDeclaredConstructors();// 遍历所有构造方法(for循环遍历数组)for (int i 0; i declaredContructors.length; i) {Constructor con declaredContructors[i];// 判断构造方法的参数是否可变System.out.println(查看是否允许带可变数量的参数 con.isVarArgs());System.out.println(该构造方法的入口参数类型依次为);// 获取所有参数类型Class[] parameterTypes con.getParameterTypes();for (int j 0; j parameterTypes.length; j) {System.out.println( parameterTypes[j]);}System.out.println(该构造方法可能拋出的异常类型为);// 获取所有可能拋出的异常类型Class[] exceptionTypes con.getExceptionTypes();for (int j 0; j exceptionTypes.length; j) {System.out.println( parameterTypes[j]);}// 创建一个未实例化的Book类实例Book book1 null;while (book1 null) {try { // 如果该成员变量的访问权限为private则拋出异常if (i 1) {// 通过执行带两个参数的构造方法实例化book1book1 (Book) con.newInstance(Java 教程, 10);} else if (i 2) {// 通过执行默认构造方法实例化book1book1 (Book) con.newInstance();} else {// 通过执行可变数量参数的构造方法实例化book1Object[] parameters new Object[] { new String[] { 100, 200 } };book1 (Book) con.newInstance(parameters);}} catch (Exception e) {System.out.println(在创建对象时拋出异常下面执行 setAccessible() 方法);con.setAccessible(true); // 设置允许访问 private 成员}}book1.print();System.out.println(\n);}}
}运行结果
查看是否允许带可变数量的参数true
该构造方法的入口参数类型依次为class [Ljava.lang.String;
该构造方法可能拋出的异常类型为class [Ljava.lang.String;
namenull
id100
price200
查看是否允许带可变数量的参数false
该构造方法的入口参数类型依次为class java.lang.Stringint
该构造方法可能拋出的异常类型为
nameJava 教程
id10
price0
查看是否允许带可变数量的参数false
该构造方法的入口参数类型依次为
该构造方法可能拋出的异常类型为
namenull
id0
price02、访问方法
1创建Method 类型的对象或数组的方法动态获取一个对象方法信息的前提
getMethods()getMethods(String name,Class? …parameterTypes)getDeclaredMethods()getDeclaredMethods(String name,Class?…parameterTypes)
2Method类常用方法和Constructor 类的常用方法类似可查看API文档或源码不再赘述 3示例 使用Method类的方法获取动态类中方法的信息 3.1创建一个Book1类编写4个不同作用域的方法。
public class Book1 { //创建Book1类static void staticMethod(){ // static作用域方法System.out.println(执行staticMethod()方法);}public int publicMethod(int i){ // public作用域方法System.out.println(执行publicMethod()方法);return 100i;}// protected作用域方法protected int protectedMethod(String s,int i) throws NumberFormatException{//NumberFormatException数字格式化异常一般是类型错误System.out.println(执行protectedMethod()方法);return Integer.valueOf(s)i; //Integer.valueOf()方法可以将String或int类型转换为包装类型Integer}private String privateMethod(String…strings){ // private作用域方法System.out.println(执行privateMethod()方法);StringBuffer sbnew StringBuffer();for (int i0;isb.length();i){sb.append(strings[i]);}return sb.toString(); //将StringBuffer转换为String类型}
}3.2创建测试类
import java.lang.reflect.Method; //导包public class Book1_Test { //创建测试类public static void main(String[] args){// 获取动态类Book1Book1 booknew Book1();Class class1book.getClass();// 获取Book1类的所有方法,返回一个数组遍历结果Method[] declaredMethodsclass1.getDeclaredMethods();for(int i0;ideclaredMethods.length;i){Method methoddeclaredMethods[i];System.out.println(方法名称为method.getName());System.out.println(方法是否带有可变数量的参数method.isVarArgs());System.out.println(方法的参数类型依次为);// 获取所有参数类型返回一个数组Class[] methodTypemethod.getParameterTypes();for(int j0;jmethodType.length;j){ //参数类型在方法里面所以用双重循环System.out.println( methodType[j]);}System.out.println(方法的返回值类型为method.getReturnType());// 获取返回值类型System.out.println(方法可能抛出的异常类型有);// 获取所有可能抛出的异常返回一个数组Class[] methodExceptionsmethod.getExceptionTypes();for(int j0;jmethodExceptions.length;j){System.out.println( methodExceptions[j]);}boolean isTurntrue;while(isTurn){try{ // 如果该成员变量的访问权限为private则抛出异常isTurnfalse;if(method.getName().equals(staticMethod)){ // 调用没有参数的方法method.invoke(book);} else if (method.getName().equals(publicMethod)) { // 调用一个参数的方法System.out.println(publicMethod(10)的返回值为 method.invoke(book, 10));} else if (method.getName().equals(protectedMethod)) { // 调用两个参数的方法System.out.println(protectedMethod(\10\,15)的返回值为 method.invoke(book, 10, 15));} else if (method.getName().equals(privateMethod)) { // 调用可变数量参数的方法Object[] parameters new Object[] { new String[] { J, A, V, A } };System.out.println(privateMethod()的返回值为 method.invoke(book, parameters));}}catch (Exception e){System.out.println(在设置成员变量值时抛出异常下面执行setAccessible()方法);method.setAccessible(true);isTurntrue;}}System.out.println(\n);}}
}运行结果
方法名称为staticMethod
方法是否带有可变数量的参数false
方法的参数类型依次为
方法的返回值类型为void
方法可能抛出的异常类型有
执行staticMethod()方法
方法名称为publicMethod
方法是否带有可变数量的参数false
方法的参数类型依次为int
方法的返回值类型为int
方法可能抛出的异常类型有
执行publicMethod()方法
publicMethod(10)的返回值为110
方法名称为privateMethod
方法是否带有可变数量的参数true
方法的参数类型依次为class [Ljava.lang.String;
方法的返回值类型为class java.lang.String
方法可能抛出的异常类型有
在设置成员变量值时抛出异常下面执行setAccessible()方法
执行privateMethod()方法
privateMethod()的返回值为
方法名称为protectedMethod
方法是否带有可变数量的参数false
方法的参数类型依次为class java.lang.Stringint
方法的返回值类型为int
方法可能抛出的异常类型有class java.lang.NumberFormatException
执行protectedMethod()方法
protectedMethod(10,15)的返回值为253、访问成员变量
1访问成员变量的方法
getFields()获取所有public修饰的成员变量 - - - getField(String name)getDeclaredFields()获取所有成员变量不考虑修饰符getDeclaredField(String name)
2Field 类的常用方法很多查看API文档或源码
getName() 获得该成员变量的名称
getType() 获取表示该成员变量的 Class 对象
get(Object obj) 获得指定对象 obj 中成员变量的值返回值为 Object 类型
set(Object obj, Object value) 将指定对象 obj 中成员变量的值设置为 value
getlnt(0bject obj) 获得指定对象 obj 中成员类型为 int 的成员变量的值
setlnt(0bject obj, int i) 将指定对象 obj 中成员变量的值设置为 i
setFloat(Object obj, float f) 将指定对象 obj 中成员变量的值设置为 f
getBoolean(Object obj) 获得指定对象 obj 中成员类型为 boolean 的成员变量的值
setBoolean(Object obj, boolean b) 将指定对象 obj 中成员变量的值设置为 b
getFloat(Object obj) 获得指定对象 obj 中成员类型为 float 的成员变量的值
setAccessible(boolean flag) 此方法可以设置是否忽略权限直接访问 private 等私有权限的成员变量
setAccessible(true)暴力反射忽略访问权限修饰符的安全检查
getModifiers() 获得可以解析出该方法所采用修饰符的整数3示例 3.1创建一个Book2类
public class Book2 { // 创建一个Book2类String name; //默认修饰public int id;private float price;protected boolean isLoan;
}3.2创建测试类
import java.lang.reflect.Field; //导包public class Book2_Test {public static void main(String[] args) {Book2 book new Book2();// 获取动态类Book2Class class1 book.getClass();// 获取Book2类的所有成员返回一个数组Field[] declaredFields class1.getDeclaredFields();// 遍历所有的成员for(int i 0;i declaredFields.length;i) {// 获取类中的成员变量Field field declaredFields[i];System.out.println(成员名称为 field.getName());Class fieldType field.getType();System.out.println(成员类型为 fieldType);boolean isTurn true;while(isTurn) {try {// 如果该成员变量的访问权限为private则抛出异常isTurn false;System.out.println(修改前成员的值为 field.get(book));// 判断成员类型是否为intif(fieldType.equals(int.class)) {System.out.println(利用setInt()方法修改成员的值);field.setInt(book, 100);} else if(fieldType.equals(float.class)) {// 判断成员变量类型是否为floatSystem.out.println(利用setFloat()方法修改成员的值);field.setFloat(book, 29.815f);} else if(fieldType.equals(boolean.class)) {// 判断成员变量是否为booleanSystem.out.println(利用setBoolean()方法修改成员的值);field.setBoolean(book, true);} else {System.out.println(利用set()方法修改成员的值);field.set(book, Java编程);}System.out.println(修改后成员的值为 field.get(book));} catch (Exception e) {System.out.println(在设置成员变量值时抛出异常下面执行setAccessible()方法);field.setAccessible(true);isTurn true;}}System.out.println(\n);}}
}运行结果
成员名称为name
成员类型为class java.lang.String
修改前成员的值为null
利用set()方法修改成员的值
修改后成员的值为Java编程
成员名称为id
成员类型为int
修改前成员的值为0
利用setInt()方法修改成员的值
修改后成员的值为100
成员名称为price
成员类型为float
在设置成员变量值时抛出异常下面执行setAccessible()方法
修改前成员的值为0.0
利用setFloat()方法修改成员的值
修改后成员的值为29.815
成员名称为isLoan
成员类型为boolean
修改前成员的值为false
利用setBoolean()方法修改成员的值
修改后成员的值为true
- 上一篇: a最先基智网站建设网站建设代码问卷调查
- 下一篇: a做爰网站wordpress采集开源
相关文章
-
a最先基智网站建设网站建设代码问卷调查
a最先基智网站建设网站建设代码问卷调查
- 站长
- 2026年02月16日
-
a站是指哪个网站南宁做网站科技公司
a站是指哪个网站南宁做网站科技公司
- 站长
- 2026年02月16日
-
asp做网站优点免费自己做网站手机软件
asp做网站优点免费自己做网站手机软件
- 站长
- 2026年02月16日
-
a做爰网站wordpress采集开源
a做爰网站wordpress采集开源
- 站长
- 2026年02月16日
-
c 手机版网站开发网站安全检测软件
c 手机版网站开发网站安全检测软件
- 站长
- 2026年02月16日
-
c 做网站好嘛网站上传百度多久收录
c 做网站好嘛网站上传百度多久收录
- 站长
- 2026年02月16日
