黑马程序员---java反射机制(一)
来源:互联网 发布:基恩士plc软件下载 编辑:程序博客网 时间:2024/06/16 09:08
java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制.就相当于一个人站在镜子面前可以看到五脏六腑一样,对于一个java的一个Class字节码文件一样,可以运用反射动态获取它里面的任意对象,任意方法。(嘿嘿!比喻不太恰当,就是想象!!!)
java程序中的各个java类,它们属于同一类事物,所以它们可以用一个类去描述,这个类就是Class。Class对应的是各个类在内存中的字节码。一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,所以它们在内存中的内容是不同的,这一个个的空间可分别用一个个的对象来表示,这些对象显然具有相同的类型,这个相同类型的类就是Class类。
Class类(获得一个类对象有四种方式)
①对象名.getClass()
②Class.forName(“类名”)(最常被使用)(会抛异常ClassNotFoundException)
③类名.class语法
④如果是Java封装类型,使用TYPE语法。(八个基本数据类型和void类型实例对象的获取)
String str1 = "abc";Class cls1 = str1.getClass();Class cls2 = String.class;Class cls3 = Class.forName("java.lang.String")Int.class = Integer.TYPE;
【java反射中的信息类】
Field,Method,Contructor,Package等等。一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象。(在java.lang.reflect包下)
Constructor类
<通过反射获取某个类中的构造方法>
得到某个类所有的构造方法:
Constructor[] constructors = Class.forName("java.lang.String").getConstructors();得到某一个构造方法:
Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);创建实例对象:
通常方式:String str = new String(new StringBuffer("abc"));反射方式:String str = constructor.newInstance(new StringBuffer("abc"));①Constructor getConstructor(Class[] params)//获取使用特殊的参数类型的公有的构造函数。
②Constructor[] getConstructors() //获得类的所有公共构造函数
③Constructor getDeclaredConstructor(Class[] params)//获取使用特定参数类型的构造函数(不限制访问 级别)
④Constructor[] getDeclaredConstructors() //获得类的所有构造函数(不限制访问级别)
Field类
<通过反射获取属性信息>
①getFields()://获得所有公有的属性
②getDeclaredFields();//获得所有的属性
③getField(String name);//获得指定名字的公有的属性
④getDeclaredField(String name);//获得指定名字的属性(不限制访问级别)
class ReflectPoint{private int x;public int y;public ReflectPoint(int x,int y){this.x = x;this.y = y;}}main方法中的代码:
ReflectPoint pt1 = new ReflectPoint(3,5);Field fieldY = pt1.getClass().getField("y");//fieldY的值是多少?是5,错!fieldY不是对象身上的变量,而是类上的,要用它去取某个对象上对应的值。System.out.println(fieldY.get(pt1));//Field fieldx = pt1.getClass().getField("x");会报一个NoSuchFieldExceptioon异常。因为x是私有的,就看不见,所以是找不到。//getField()只能得到那些看得见(非私有)的成员变量。//getDeclaredField()管你可见不可见都能得到。Field fieldX = pt1.getClass().getDeclaredField("x");//用getDeclaredField()得到了私有的变量X,这时能够看得见了,但之后通过fieldX.get(pt1)还是会报错,//是因为x是私有的,之前只是让你能够看得见,但还是不让你拿到。//通过setAccessible()设置为true就能够拿到,可以访问,这就俗称的暴力反射,不管你是私有还是非私有都要访问。fieldX.setAccessible(true);System.out.println(fieldX.get(pt1));Method类
<通过反射获取成员方法>
①getMethods();//获得所有公有的成员方法,包括从父类或者接口继承过来的公有方法。
②getDeclaredMethods();//获得所有的成员方法
③getMethod(name,parm);//获得指定参数类型的公有的成员方法
④getDeclaredMethod(name,parm);//获得指定参数类型的成员方法,可以使私有的。
得到类中的某一个方法:Method charAt = Class.forName("java.lang.String").getMethod("CharAt",int.class);调用方法:
通常方式:System.out.println(str.charAt(1));
反射方式:System.out.println(charAt.invoke(str,1));
如果传递给Method对象的invoke()方法的第一个参数为null则说明该Method对象对应的是一个静态方法。
jdk1.5:public Object invoke(Object obj,Object...args)
jdk1.4:public Object invoke(Object obj,Object[] args),
需要将一个数字作为参数传递给invoke方法时,数组中的每个元素分别对应被调用方法中的一个参数,所以,调用charAt方法的代码也可以用jdk1.4改写为charAt.invoke("str",new Object[]{1})形式。
String str = "abc"; Method methodCharAt = String.class.getMethod("charAt",int.class); System.out.println(methodCharAt.invoke(str,1));//b System.out.println(methodCharAt.invoke(str,new Object[]{2}));//cInterface
<通过反射获取接口信息>
①getGenericInterfaces()//返回表示某些接口的Type,这些接口由此对象所表示的类或接口直接实现。②getInterfaces//确定此对象所表示的类或接口实现的接口。
c = Class.forName("Person");Class[] interfaces = c.getInterfaces();for(int i = 0;i<interfaces.length;i++){ System.out.println(interface[i].toString());}SuperClass
<通过反射获取父类信息>
①getSuperclass// 返回表示此Class
所表示的实体(类、接口、基本类型或 void)的超类的Class
。
c = Class.forName("Person");System.out.println("获得父类信息");Class sc = c.getSuperclass();System.out.println(sc.toString());Array类
<Array工具类>
Person[] persons = new Person[]{new Person("张三",18);new Person("李四",19);new Person("王五",20);};System.out.println("对象数组的长度:"+Array.getLength(persons));//对象数组的长度:3Class c2 = Person.class;//c2是一个类类型。System.out.println("是否是数组类型:"+c2.isArray());//是否是数组类型:falseClass c = persons.getClass();System.out.println("是否是数组类型:"+c.isArray());//是否是数组类型:true//使用Array类遍历数组for(int i=0;i<Array.getLength(persons);i++){System.out.println(Array.get(persons,i);//姓名:张三,年龄:18//姓名:李四,年龄:19//姓名:王五,年龄:20}
【总结】反射就是对java所有类(包括接口)、方法、属性的一个映射表现形式,可以对所有类、方法、属性进行操作, 使得java语言更加灵活,更易于对事物的操作和描述,既而更深化它本身成为面向对象语言的特性。反射重点在Class、Field、Construct、Method、Interface、SuperClass、Array等的描述,灵活运用以上的类及方法,反射基础这一关应该就过了!!!
---------------------- Android培训、java培训、期待与您交流! ----------------------详细请查看:www.itheima.com
- 黑马程序员---java反射机制(一)
- 黑马程序员_JAVA反射机制(一)
- 《黑马程序员》反射机制《一》
- "黑马程序员"java反射机制(1)
- “黑马程序员”java反射机制(2)
- 黑马程序员-Java反射机制
- 黑马程序员-java反射机制
- 黑马程序员-Java反射机制
- 黑马程序员-JAVA反射机制
- 黑马程序员-Java反射机制
- 黑马程序员-JAVA反射机制
- 黑马程序员 java反射机制
- 黑马程序员---Java反射机制
- 【黑马程序员】Java反射机制
- 黑马程序员-Java反射机制
- 黑马程序员--Java 反射机制
- 黑马程序员-Java反射机制
- 黑马程序员---JAVA反射机制
- Java英文单词Java基础常见英语词汇
- SQL Server 中统计每个数据表的大小
- maven创建及maven2的常用命令
- 央视解读30万年薪公务员:公务员或将普遍涨薪
- Hibernate双向N-N关联
- 黑马程序员---java反射机制(一)
- 求一个范围中1的个数
- MySql GUI管理工具 MySQL Workbench
- const char * 和 std::string.c_str()是个危险的东西!
- Android发展历史
- H3C ER3200路由器安装MRTG监控网络流量
- 编一个简单的小游戏怎么删除一个用户和删除所有用户
- UVALive - 4108 SKYLINE (线段树的区间修改)
- Python:如何获取当前的日期和时间