JAVA中的反射是什么?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
反射的使用
获取Class对象的三种方式
1 Object ——> getClass();
2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
3 通过Class类的静态方法:forName(String className)(常用)
我们先通过一个例子分别对这三种获取class进行实现
package reflect2;
/**
* 获取Class对象的三种方式
* 1 Object ——> getClass();
* 2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
* 3 通过Class类的静态方法:forName(String className)(常用)
*
*/
public class Fanshe {
public static void main(String[] args) {
//第一种方式获取Class对象
Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。
Class stuClass = stu1.getClass();//获取Class对象
System.out.println(stuClass.getName());
System.out.println(stuClass);
//第二种方式获取Class对象
Class stuClass2 = Student.class;
System.out.println(stuClass == stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个
System.out.println(stuClass2);
//第三种方式获取Class对象
try {
Class stuClass3 = Class.forName("reflect2.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象
System.out.println(stuClass3);
} catch (ClassNotFoundException e) {
System.out.print("error");
//e.printStackTrace();
}
}
}
package reflect2;
public class Student {
//---------------构造方法-------------------
//(默认的构造方法)
Student(String str){
System.out.println("(默认)的构造方法 s = " + str);
}
//无参构造方法
public Student(){
System.out.println("调用了公有、无参构造方法执行了。。。");
}
//有一个参数的构造方法
public Student(char name){
System.out.println("姓名:" + name);
}
//有多个参数的构造方法
public Student(String name ,int age){
System.out.println("姓名:"+name+"年龄:"+ age);//这的执行效率有问题,以后解决。
}
//受保护的构造方法
protected Student(boolean n){
System.out.println("受保护的构造方法 n = " + n);
}
//私有构造方法
private Student(int age){
System.out.println("私有的构造方法 年龄:"+ age);
}
}
执行后,
发现三种方法都可以成功调用class方法。因为Object类中的getClass方法、因为所有类都继承Object类。从而调用Object类来获取。
三种方式常用第三种,第一种对象都有了还要反射干什么。第二种需要导入类的包,依赖太强,不导包就抛编译错误。一般都第三种,一个字符串可以传入也可写在配置文件中等多种方法
除此之外还有一些其他的方法需要用到
static Class forName(String className)返回描述类名为className的Class对象
Object newInstance() 返回这个类的新实例
Object newInstance(Object[] args) 构造一个这个构造器所属类的新实例
参数 args 这是提供构造器的参数。
void printStackTrace() 将Throwable对象和栈的轨迹输出到便标准错误流
Field[] getFields()
Field[] getDeclaredFields()
getFields方法也将返回包含Field对象的数组,这些对象记录了这个类的全部公有域
getDeclaredFields方法也将返回包含Field对象的数组,这些对象记录了这个类的全部域
Method[] getMethods()
Method[] getDeclaredMethods()
返回包含Method对象的数组,getMethods方法将返回所有的共有方法,包括从超类继承来的公有方法。
getDeclaredMethods返回这个类的全部方法,但是不包括从超类继承来的方法。
Constructor[] getConstructors()
Constructor[] getDeclaredConstructors()
返回包含Constructor对象的数组,其中包含Class对象描述的类的所有公有构造器(getConstructors)。或所有构造器
Class getDeclaringClass()
返回一个用于描述类中定义的构造器方法或者与的Class对象
Class getExceptionTypes() 在Constructor和Method类返回一个用于描述方法抛射出异常类型的Class对象数组
int getModifiers() 返回一个用于描述构造器 方法或者与的修饰符的整形数据,使用Method可以分析这个返回值
String getName 返回一个用于描述构造器 方法或者与的字符串
Class[] getParameterTypes() 在Constructor和Method类返回一个用于描述参数类型的Class对象数组
Class[] getReturnType()在Method类返回一个用于描述返回类型的Class对象
上面的一些实现
package reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;
public class ReflectionTest extends ReflectionTestFather{
public static void main(String[] args) {
// TODO Auto-generated method stub
String name;
if(args.length>0) name=args[0];
else {
Scanner in=new Scanner(System.in);
System.out.println("Enter class name (e.g. java.util.Date):");
name=in.next();
}
try {
Class cl=Class.forName(name);
Class supercl=cl.getSuperclass();
String modifiers=Modifier.toString(cl.getModifiers());
if(modifiers.length()>0) System.out.println(modifiers+"");
System.out.println("class"+name);
if(supercl!=null&&supercl!=Object.class)System.out.println("extends"+supercl.getName());
System.out.println("\n{\n");
printConstructors(cl);
System.out.println();
printMethods(cl);
System.out.println();
printFields(cl);
System.out.println("}");
}
catch(ClassNotFoundException e){
e.printStackTrace();
}
System.exit(0);
}
public static void printConstructors(Class cl){
Constructor[] constructors=cl.getDeclaredConstructors();
for(Constructor c:constructors)
{
String name=c.getName();
System.out.println(" ");
String modifiers=Modifier.toString(c.getModifiers());
if(modifiers.length()>0)
System.out.println(modifiers+"");
System.out.println(name+"(");
Class[] paramTypes=c.getParameterTypes();
for(int j=0;j<paramTypes.length;j++)
{
if(j>0)
System.out.println(",");
System.out.println(paramTypes[j].getName());
}
System.out.println(");");
}
}
public static void printMethods(Class cl)
{
Method[] methods= cl.getMethods();
for(Method m:methods)
{
Class retType= m.getReturnType();
String name=m.getName();
System.out.println(" ");
String modifiers=Modifier.toString(m.getModifiers());
if(modifiers.length()>0)
System.out.println(modifiers +" ");
System.out.println(retType.getName()+" "+name+"(");
Class[] paramTypes=m.getParameterTypes();
for(int j = 0;j<paramTypes.length;j++)
{
if(j>0)
System.out.println(", ");
System.out.println(paramTypes[j].getName());
}
System.out.println(");");
}
}
public static void printFields(Class cl) {
Field[] fields=cl.getFields();
for(Field f:fields)
{
Class type=f.getType();
String name=f.getName();
System.out.println(" ");
String modifiers=Modifier.toString(f.getModifiers());
if(modifiers.length()>0)
System.out.println(modifiers+" ");
System.out.println(type.getName()+" "+name+";");
}
}
}
package reflection;
public class ReflectionTestFather {
public static void main(String[] args) {
// TODO Auto-generated method stub
int key=0;
}
public void tryTest() {
System.out.println("由父类继承的方法");
}
public ReflectionTestFather() {
System.out.println("这是父类的构造器");
}
public ReflectionTestFather(String key) {
System.out.println("这是父类的构造器");
}
}
执行输入:reflection.ReflectionTest
回车键结果为:
Enter class name (e.g. java.util.Date):
reflection.ReflectionTest
public
classreflection.ReflectionTest
extendsreflection.ReflectionTestFather
{
public
reflection.ReflectionTest(
);
public static
void main(
[Ljava.lang.String;
);
public static
void printConstructors(
java.lang.Class
);
public static
void printMethods(
java.lang.Class
);
public static
void printFields(
java.lang.Class
);
public
void tryTest(
);
public final native
void wait(
long
);
public final
void wait(
long
,
int
);
public final
void wait(
);
public
boolean equals(
java.lang.Object
);
public
java.lang.String toString(
);
public native
int hashCode(
);
public final native
java.lang.Class getClass(
);
public final native
void notify(
);
public final native
void notifyAll(
);
}
本文参考于原文:https://blog.csdn.net/sinat_38259539/article/details/71799078