什么是java反射机制
反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性。rol.
通过反射,我们可以在运行时获得程序或程序集中每一个类型的成员和成员的信息。
程序中一般的对象的类型都是在编译期就确定下来的,而Java反射机制可以动态地创建对象并调用其属性,这样的对象的类型在编译期是未知的。所以我们可以通过反射机制直接创建对象,即使这个对象的类型在编译期是未知的。
反射的核心是JVM在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。
Java反射框架主要提供以下功能:
- 1.在运行时判断任意一个对象所属的类;
- 2.在运行时构造任意一个类的对象;
- 3.在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用private方法);
- 4.在运行时调用任意一个对象的方法
重点:是运行时而不是编译时
反射的主要用途
本人现在正在写一些反射基础的应用
获取某个Class对象的方法集合,主要有以下几个方法:
getDeclaredMethods()方法返回类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。
|
|
getMethods()方法返回某个类的所有公用(public)方法,包括其继承类的公用方法。
|
|
getMethod方法返回一个特定的方法,其中第一个参数为方法名称,后面的参数为方法的参数对应Class的对象
下面我们通过一个例子来看这些方法//用反射调用方法
Method m=null;//创建一个Method的实体化对象
try {
m=s.getDeclaredMethod("friendlyStudy", int.class);
m.invoke(stu, 3);
m=s.getDeclaredMethod("privateStudy", int.class);
m.setAccessible(true);//调用私用方法
m.invoke(stu, 78);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
System.out.println("----------------------");
System.out.println("调用构造方法");
//调用构造方法
Constructor<?>[] cons=null;
try {
cons=s.getDeclaredConstructors();//取得public的构造函数
for (Constructor<?> constructor : cons) {
System.out.println(constructor);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
System.out.println("---------------------------");
System.out.println("调用构造方法中的具体一个方法");
Constructor<?>con=null;
try {
con=s.getConstructor(String.class,int.class);
stu=(Student)con.newInstance("zhangs",88);
System.out.println(stu.name);
System.out.println(stu.getAge());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
System.out.println("=================================");
System.out.println("调用构造方法中的具体一个方法2");
Class<?> c=stu.getClass();
Constructor<?>con1=null;
try {
con1=c.getDeclaredConstructor(String.class);
con1.setAccessible(true);
stu=(Student)con1.newInstance("海绵宝宝 da shabi");
System.out.println(stu.name);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
System.out.println("=================================");
System.out.println("调用构造方法中的具体一个方法3");
Class<?> cc=null;
Constructor<?>con3=null;
try {
cc=Class.forName("javaoopFanshe1127.Student");
con3=cc.getDeclaredConstructor(String.class);
con3.setAccessible(true);
stu=(Student)con3.newInstance("海绵宝宝 ");
System.out.println(stu.name);
} catch (Exception e) {
// TODO: handle exception
}
}
-----------------------------------------------------------------------------
调用friendlyStudy学习时间是:3
调用privateStudy学习时间是:78
----------------------
调用构造方法
public javaoopFanshe1127.Student(java.lang.String,int)
private javaoopFanshe1127.Student(java.lang.String,java.lang.String)
private javaoopFanshe1127.Student(java.lang.String)
public javaoopFanshe1127.Student()
---------------------------
调用构造方法中的具体一个方法
zhangs
88
=================================
调用构造方法中的具体一个方法2
海绵宝宝 da shabi
=================================
调用构造方法中的具体一个方法3
海绵宝宝
数组在Java里是比较特殊的一种类型,它可以赋值给一个Object Reference。下面我们看一看利用反射创建数组的例子:
|
|
其中的Array类为java.lang.reflect.Array类。我们通过Array.newInstance()创建数组对象,它的原型是:
|
|
而newArray()方法是一个Native方法,它在Hotspot JVM里的具体实现我们后边再研究,这里先把源码贴出来
|
|
源码目录:openjdk\hotspot\src\share\vm\runtime\reflection.cpp
|
|
另外,Array类的set()和get()方法都为Native方法,在HotSpot JVM里分别对应Reflection::array_set和Reflection::array_get方法,这里就不详细解析了。