------ >Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
Java反射机制主要提供了以下功能:
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法;生成动态代理。
反射机制中的Class 类十分特殊。它和一般Java类一样继承自Object,其实体用以表达Java程序运行时的类(classes)和接口(interfaces),Class类是反射(Reflection)的起源。针对任何您想探勘的类(class),唯有先为它产生一个Class对象(object),接下来才能经由后者唤起为数十多个的Reflection APIs。
Class类 提供获取字节码中的内容,比如名称,字段,构造函数,一般函数,该类可以获取字节码文件中的所有内容,反射就是依靠该类完成。想要对一个类文件解刨,只要获取到该类的字节码文件对象。
获取字节码文件的方式:
方式一:Object类中的getclass()方法,想要用这种方法,必须要明确具体的类,并创建对象,这种方法稍显麻烦。
方式二:任何数据类型都具备一个静态的属性.class方法来获取其对应的class对象,这种方法相对简单,但还是要明确用到类中的静态成员,扩展性还是不够。
方式三:只要通过给定类的字符串名称就可以获取该类,扩展性最强。
可以用Class类中的forName方法完成,种方式只要有名称即可,更加方便。
三种获取方法演示代码如下:
class RefelectDemo
{
public static void main(String[] args) throws ClassNotFoundException
{
//getClassObject_1();
//getClassObject_2();
getClassObject_3();
}
private static void getClassObject_3() throws ClassNotFoundException //方式三
{
String className="Person";
Class clazz = Class.forName(className);
System.out.println(clazz);
}
private static void getClassObject_2()//方式二
{
Class clazz = Person.class;
Class clazz1= Person.class;
System.out.println(clazz==clazz1);
}
public static void getClassObject_1() //方式一
{
Person p = new Person();
Class clazz = p.getClass();
Person p1=new Person();
Class clazz1=p1.getClass();
System.out.println(clazz==clazz1);
}
}
<pre name="code" class="java">class Person
{
private int age;
private String name;
public Person(int age, String name)
{
super();
this.age = age;
this.name = name;
System.out.println("Person param run..."+this.name+":"+this.age);
}
public Person()
{
super();
System.out.println("person run");
}
public void show()
{
System.out.println(name+"...show run..."+age);
}
private void method()
{
System.out.println("method run");
}
public void paramMethod(String str,int num)
{
System.out.println("paramMethod run..."+str+":"+num);
}
}
使用Java中的反射机制可以获取class中的构造函数, 会用到constructor 构造器,代码实现如下:
import java.lang.reflect.*;
class RefelectDemo2
{
public static void main(String[] args) throws Exception
{
//creatNewObject_1();
creatNewObject_2();
}
public static void creatNewObject_1() throws Exception
{
//Person p=new Person(); //早期方法
//现在:
String name="Person";
Class clazz = Class.forName(name); //寻找该名称类文件,加载进内存,产生class对象
Object obj = clazz.newInstance();//产生该类的对象
}
public static void creatNewObject_2() throws Exception
{
//Person p=new Person("小强",39); //之前用法
//当获取指定名称对应类中所体现的对象时,该对象初始化不使用空参数构造时,
//应该先获取到该构造函数,通过字节码文件对象即可完成,该方法是 getConstructor(paramterTypes)
String name="Person";
Class clazz = Class.forName(name);
Constructor constructor=clazz.getConstructor(String.class,int.class);
//通过该构造器对象的newInstance方法进行对象的初始化
Object obj= constructor.newInstance("小明",39);
}
}
使用反射获取class中的字段Field,代码实现如下:
import java.lang.reflect.*;
class ReflectDemo3
{
public static void main(String[] args) throws Exception
{
getFieldDemo();
}
public static void getFieldDemo() throws Exception
{
Class clazz = Class.forName("Person");
Field field = clazz.getDeclaredField("age"); //只获取本类字段,包含私有
field.setAccessible(true);//对私有字段的访问取消权限检查,暴力访问
Object obj=clazz.newInstance();
field.set(obj,89);
Object o = field.get(obj);
System.out.println(o);
}
}
使用反射也获取class中的方法,代码实现如下:
import java.lang.reflect.*;
class ReflectDemo4
{
public static void main(String[] args) throws Exception
{
// getMethodDemo_1();
getMethodDemo_2();
}
public static void getMethodDemo_1() throws Exception//获取指定class中所有方法
{
Class clazz= Class.forName("Person");
//Method[] methods = clazz.getMethods(); //获取的都是公有方法
Method[] methods = clazz.getDeclaredMethods(); //只获取本类方法,包含私有方法
for ( Method method: methods)
{
System.out.println(method);
}
}
public static void getMethodDemo_2() throws Exception //获取class中某一个方法
{
Class clazz= Class.forName("Person");
Method method = clazz.getMethod("show",null);//获取空参数一般方法
Constructor constructor = clazz.getConstructor(String.class,int.class);
Object obj = constructor.newInstance("小强",37);
method.invoke(obj,null);
}
}