首页 / JAVA / Java反射机制详解
Java反射机制详解
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java反射机制详解,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3958字,纯文字阅读大概需要6分钟。
内容图文
概述
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。
总结:反射就是把java类中的各种成分映射成一个个的Java对象。
Java反射机制可以让我们在编译期(Compile Time)之外的运行期(Runtime)获得任何一个类的字节码。包括接口、变量、方法等信息。还可以让我们在运行期实例化对象,通过调用get/set方法获取变量的值。
如果由Java的类实例化对象叫做"正",那么由一个对象反推出的类就叫做"反射"。
反射机制能做什么?
反射机制主要提供了以下的功能:
- 在运行时判断任意一个对象所属的类
- 在运行时构建任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的方法
- 生成动态代理
·反射和类的关系:
在程序运行状态中,对任意一个类(指class文件),都能够知道这个类的所有属性和方法。
·反射和类对象的关系:
反射对于某一个类的一个对象,都能够调用它的任意一个方法和属性。
·Java反射机制:
通俗地描述Java反射机制:能够动态地获取对象的信息,就称之为反射。
·java反射机制的好处:
极大的提高了应用程序的扩展性。在反射以前,一般使用多态来提高扩展性,将子类对象传递给父类引用来实现的。但这种方式必须要通过new来建立子对象,子类对象必须写死在代码中。而有了反射之后,就可以通过反射来省略掉new子类对象这一个步骤。
反射直接将子类对象的类名以字符串的形式传递给反射技术框架并由反射技术框架来创建这个字符串代表的类的实例。
反射的另类理解
- 反射就是把Java类中的各个成分映射成相应的类
- 一个Java类的组成:成员变量、成员方法、构造方法、修饰符、包等。
- Java中的一个指定的类中的每一个成员都可以用相应的Java反射类的API的一个实例来表示。
Class类简介
Class对象
虚拟机在class文件的加载阶段,把类的信息保存在方法区数据结构中,并在java堆中生成一个Class对象,作为类信息的入口。
获取Class对象的三种方式
定义两个类,Student.java
和Teacher.java
class Student{
private String name;
private int age;
static{
System.out.println("Student");
}
}
class Teacher{
private String name;
private int age;
static{
System.out.println("Teacher");
}
}
1.通过实例变量方式
public class Test{
public static void main(Strint args[]){
Student student = new Student();
Class clazz = student.getClass();
}
}
2.通过类名的方式
public Class Test{
public static void main(String args[]){
Class clazz = Student.class;
}
}
使用这种方法时,只会加载Student类,不会触发其类构造器的初始化。
3.通过Class.forName()
的方式
public class Test{
public static void main(String args[]){
Class clazz = Class.forName("com.Student");
}
}
在JDK源码的实现中,forName方法会调用Native方法forName0(),它在JVM中调用findClassFromClassLoader()加载Student类,其原理和ClassLoader相同,将会触发Student类的类构造器初始化。
forName0()方法声明如下:
private static native Class<?> forName0 (String name,booelan intialize,ClassLoader loader,Class<?> caller)
其中intialize参数用来告诉虚拟机是否要对加载的类进行初始化,如果为false,则不会进行初始化。
反射机制reflect
1.获取类字段
Class class_student = Student.class;
Field[] field = class_student.getDeclaredFields();
for(Field field : fields){
System.out.println(field.getName());
}
2.获取类方法
Class class_student = Student.class;
Method[] methods = class_student.getDeclaredMethods();
for(Method method : methods){
System.out.println(method);
}
3.获取对应的实例构造器,并生成实例
public class ClassTest{
public static void main(String args[]) throws NoSuchMethodException {
Class class_student = Student.class;
Constructor constructor = class_student.getConstructor(String.class,int.class);
constructor.newInstance("Tom",10);
}
}
class Student{
private String name;
private int age;
public Student(String name, int age){
this.name=name;
this.age=age;
}
}
如果没有显示的声明默认构造器,class_student.getConstructor()会抛出NoSuchMethodException异常。
4.通过newInstance()
方法生成类实例
Class class_student = Student.class;
Student student = class_student.newInstance();
5.设置私有变量
Class class_student = Student.class;
Field name = class_student.getDeclaredField("name");
name.setAccessible(true);
Student student = (Student)class_student.newInstance();
name.set(student,"name");
6.获取私有变量
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
return (Unsafe)f.get(null);
这种方式在使用Unsafe类进行黑魔法时经常用到。
反射应用场景
加载数据库驱动
Class.forName
的一个很常见的方法是在加载数据库驱动的时候。
例:
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection conn = DriverManager.getConnection("jdbc.sqlserver://localhost:1433;DatabaseName=jieshou","jieshou","jieshou");
为什么我们在加载数据库驱动包的时候没有使用newInstance()方法呢?即有的jdbc数据库连接的写法为Class.forName("xx.xx.xx");
,而也有的写法为Class.forName("xx.xx.xx").newInstance();
.这是因为Class.forName("");的作用为要求JVM查找并加载指定的类,如果在类中有静态初始器的话,JVM就会执行该类的静态代码段。而在jdbc的规范中明确要求这个Driver类必须向DriverManager注册自己,即任何一个JDBCDriver的Driver类代码都必须类似如下:
public class MyJDBCDriver implements Driver{
static{
DriverManager.registerDriver(new MyJDBCDriver());
}
}
既然在静态初始化器中已经完成注册,所以在使用JDBC的时候只需要写Class.forName("");
就可以了。
原文:https://www.cnblogs.com/jieshou/p/14529388.html
内容总结
以上是互联网集市为您收集整理的Java反射机制详解全部内容,希望文章能够帮你解决Java反射机制详解所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。