您的位置:首页 > 职场人生

黑马程序员_java的反射机制

2013-03-24 16:12 489 查看
黑马程序员_java反射机制
[align=center]------android培训java培训、期待与您交流!------[/align]

什么是反射:反射其实就加载类解剖类的组成部分。
通常在写框架时,就需要使用大量的反射技术来完成一些操作。
在java中如何来使用反射技术?
1.获取此类的字节码对象。可以通过java中最常见的三种方式获取。
(1)Class.forName("类的完整路径");//就是包名加类名
(2)类名.class
(3)对象名.getClass();
2.解剖里面类中的组成部分,分别是(成员变量,成员函数,构造函数)。
同过Class类中的一些方法可以实现,分别是:
getFields()//获取此类的所有public修饰的字段
getMethods();获取此类的所有public修饰的函数
getConstructors();//获取此类所有被public修饰的构造函数
getField(name)//获取此类被public修饰名为name的字段
getMethod(name,Types)//获取此类被public修饰名为name,参数为Types的方法,因为参数可以有多个,所以Types是可变参数类型
getConstructor(Types)//根据Types参数获取此类被public修饰的构造函数,Types是可变参数类型。
----------------------------------------------
getDeclaredFields()//获取此类所有的字段,也包含私有的。
getDeclaredMethods();获取此类的所有的函数,也包含私有的
getDeclaredConstructors();获取此类的所有的构造函数,也包含私有的
getDeclaredField(name)//获取此类中为名name的字段,也包含私有的
getDeclaredMethod(name,Types)//获取此类的名为name,参数为Types的方法,因为参数可以有多个,所以Types是可变参数类型,也包含私有的。


getDeclaredConstructor(Types)//根据Types参数获取此类的构造函数,Types是可变参数类型,也包含私有的。

(1)(通过反射获取字段,并使用)
package Test;
import java.lang.reflect.Field;
class Person{
public String name;
}
public class Demo1 {
public static void main(String[] args)throws Exception{
Class clazz=Class.forName("Test.Person");//获得Person类字节码对象
Person p=new Person();
Field fieName=clazz.getField("name");
String str=(String)fieName.get(p);//获取p对象中的name字段的值
}
}
(2)(通过反射获取成员函数,并调用)
package Test;
import java.lang.reflect.Method;

class Person{
public void show(){
System.out.println("我是无参show方法");
}
public void show(String name){
System.out.println("我是有参"+name);
}
}
public class Demo1 {
public static void main(String[] args)throws Exception{
Class clazz=Class.forName("Test.Person");//获得Person类字节码对象
Person p=new Person();
Method metShow=clazz.getMethod("show",null);//获取无参show方法,没参所以传null
Method metShow2=clazz.getMethod("show",String.class);//获取有参show方法。
metShow.invoke(p,null);//用p对象调用此方法
metShow2.invoke(p,"show方法");
}
}
(3)(通过反射获取构造函数,并创建对象)

package Test;
import java.lang.reflect.Constructor;

class Person{
public Person(){
System.out.println("调用无参构造函数创建对象");
}
public Person(int age,String name){
System.out.println("调用有参构造函数创建对象");
}
}
public class Demo1 {
public static void main(String[] args)throws Exception{
Class clazz=Class.forName("Test.Person");//获得Person类字节码对象
Constructor constru1=clazz.getConstructor(null);//获取此类的无参构造函数
Constructor constru2=clazz.getConstructor(int.class,String.class);//获取此类多参的构造函数
constru1.newInstance(null);//调用无参构造函数创建对象
constru2.newInstance(34,"黑马_小爻");//调用多参构造函数创建对象
}
}


如果是非public修饰的成员如何获取并使用呢?
我就举一个例子,因为其他的都一样
案例(获取非public修饰的成员的函数并调用)
package Test;
import java.lang.reflect.Method;

class Person{
private void show(){
System.out.println("我来了,黑马!!");
}
}
public class Demo1 {
public static void main(String[] args)throws Exception{
Class clazz=Class.forName("Test.Person");
Person p=new Person();
Method method=clazz.getDeclaredMethod("show",null);//由show方法时private的,所以只能通过getDeclaredMethod方法才能获得
method.setAccessible(true);//这里为true代表java使用它时不对其进行访问权限语法检查
method.invoke(p,null);

}
}


有一件事情值得注意,如果方法的参数为数组类型,通过反射获取此方法时一定要记得将数组强转为Object
如:通过反射获取main方法。
package Test;
import java.lang.reflect.Method;

class Person{
public static void main(String[] args){
System.out.println("Person");
}
public static void show(Object[] obj){
System.out.println(obj.length);
}
}
public class Demo1 {
public static void main(String[] args)throws Exception{
Class clazz=Class.forName("Test.Person");
Method met=clazz.getMethod("main",String[].class);
met.invoke(null,(Object)new String[]{"你好黑马"});
/*为什么要将String数组强转为Object对象呢?
* 这是java升级后遗留下来的问题,因为在java1.4版本的时候,还没有可变参数类型时,我们这里参数类型是一个Object[]数组
* 我们把Object数组中的每个角标元素来出来当方法参数。来确定我们要获取的方法
* 1.5有了可变参数后,java为了使旧版本能够兼容新版本,所以只要你传数组,还是按老办法获取方法
* 所以上面的运行实际是把数组拆开后把其中的元素传进去的,并不是把String数组传进去的。
* */
}
}


邮箱:wolaoben7252@qq.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: