黑马程序员——反射
2015-07-31 22:59
633 查看
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
反射
理解反射的概念
Class类
注意:
1、int.class == Integer.TYPE。
2、数组类型的Class实例对象Class.isArray()为true。
3、反射并不是Java 5.0的新特性。
常用方法
*构造方法的反射应用(Coustructor类)*
Constructor类的实例对象代表类的一个构造方法。
反射公共,私有和保护的构造方法:
Constructor对象代表一个构造方法,Constructor对象有的方法:得到构造方法名字,得到所属于的类,产生实例对象。
利用构造方法创建实例对象:
调用获得的方法时要用到上面相同类型的实例对象
通过Class类中的newInstance()方法也可创建类的实例,其内部工作原理是先得无参的构造方法,再用构造方法创建实例对象。
*成员变量的反射(Field类)*
Field类代表反射某个类中的一个成员变量。
注意访问权限的问题)也就是说,定义的是类对象,而非对象的对象。
代码示例
练习:将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的”CSDN社区”通过反射改成”黑马论坛”。
成员方法的反射(Method类)
Method类代表某个类中的一个成员方法
得到类中的某一个方法:
如果传递给Method对象的invoke()方法的第一个参数为null,这有着什么样的意义呢?
JDK1.4和JDK1.5的invoke方法的区别:
目标:写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法。
*数组与Object的关系及其反射类型*
Arrays.asList()方法处理int[]和String[]时的差异。
反射
理解反射的概念
反射就是把Java类中的各种成分映射相成Java类。 例如:众多的人用一个Person类来表示,那么众多的Java类就用一个Class类来表示。
Class类
Class类用于表示.class文件,是所有加载进内存的字节码对象的父类。所以可以通过Class得到运行时的类。 同一个类实例化的不同对象得到的字节码是同一个
注意:
1、int.class == Integer.TYPE。
2、数组类型的Class实例对象Class.isArray()为true。
3、反射并不是Java 5.0的新特性。
常用方法
System.out.println("判断int基本数据类型和Integer的基本数据类型" + "是不是同一个Class对象 结果为:"+(int.class == Integer.TYPE)); System.out.println("判断int.class是不是基本数据类型 结果为:"+int.class.isPrimitive()); System.out.println("判断是不是数组类型 结果为:"+int[].class.isArray());
*构造方法的反射应用(Coustructor类)*
Constructor类的实例对象代表类的一个构造方法。
反射公共,私有和保护的构造方法:
反射公共的需要的方法是:getConstructor(); 反射私有的需要的方法是:getDeclaredConstructor();
Constructor对象代表一个构造方法,Constructor对象有的方法:得到构造方法名字,得到所属于的类,产生实例对象。
得到某个类空参数构造方法,例: Constructor constructor = Class.forName("java.lang.String").getConstructor(); 得到某个类所有的构造方法,例: Constructor [] constructors= Class.forName("java.lang.String").getConstructors(); 得到某一个带参数的构造方法,例: Constructor constructor =Class.forName("java.lang.String").getConstructor(StringBuffer.class);
利用构造方法创建实例对象:
通常方式:String instance = new String(new StringBuffer("黑马程序员")); 反射方式:String instance = (String)constructor.newInstance("黑马程序员");
调用获得的方法时要用到上面相同类型的实例对象
通过Class类中的newInstance()方法也可创建类的实例,其内部工作原理是先得无参的构造方法,再用构造方法创建实例对象。
*成员变量的反射(Field类)*
Field类代表反射某个类中的一个成员变量。
注意访问权限的问题)也就是说,定义的是类对象,而非对象的对象。
代码示例
package com.itheima.study; public class Person { public int age; private int height; public Person(int age,int height){ this.age=age; this.height=height; } } package com.itheima.study; import java.lang.reflect.Field; public class ReflectTest{ public static void main(String...args) throws Exception{ Person p = new Person(20,30); Field fieldAge = p.getClass().getField("age"); System.out.println(fieldAge.get(p)); } }
注意:如果类的某个成员变量的修饰符是private,那么直接通过getField方法获取Field类型的对象就会出现错误。那么直接通过getDeclaredField方法获取Field。 通过称之为暴力反射的方式解决,也就是使用setAccessible(true)使private类型的成员变量也可以被获取值。
练习:将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的”CSDN社区”通过反射改成”黑马论坛”。
package 遍历E盘; public class fanshe { public String str1 = "CSDN社区"; public String str2 = "黑马程序员"; public String str3 = "啊苏打水"; @Override public String toString() { return str1 + "++" + str2 + "++" + str3; } } package 遍历E盘; import java.lang.reflect.Field; public class fanshe1 { public static void main(String[] args) throws Exception { // TODO Auto-generated method stub fanshe f = new fanshe(); changeStringValue(f); System.out.println(f); } private static void changeStringValue(Object f) throws Exception, Exception { // TODO Auto-generated method stub Field[] ff= f.getClass().getFields(); for (Field i:ff) { String s1=(String)i.get(f);//获取实例化对象所对应的字段值 String newValue = s1.replace("CSDN社区", "黑马论坛" ); i.set(f, newValue);//修改值 } } }
成员方法的反射(Method类)
Method类代表某个类中的一个成员方法
得到类中的某一个方法:
例子 Method charAt = Class.forName("java.lang.String").getMethod("charAt", 调用方法: 通常方式:System.out.println(str.charAt(1)); 反射方式:System.out.println(charAt.invoke(str, 1));
如果传递给Method对象的invoke()方法的第一个参数为null,这有着什么样的意义呢?
说明该Method对象对应的是一个静态方法!
JDK1.4和JDK1.5的invoke方法的区别:
JDK1.4:public Object invoke(Object obj,Object[] args) JDK1.5:public Object invoke(Object obj,Object... args)
目标:写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法。
package com.itheima.day01; import java.lang.reflect.Method; public class ReflectTest { public static void main(String[] args) throws Exception { Class clszz = Class.forName(args[0]); Method main = clszz.getMethod("main", String[].class); main.invoke(null,"黑马程序员","黑马论坛","CSDN社区"); } }
*数组与Object的关系及其反射类型*
具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。 基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用; 非基本类型的一维数组,既可以当做Object类型使用,又可以当做Object[]类型使用。
Arrays.asList()方法处理int[]和String[]时的差异。
int[] arr =new int[] { 1, 2, 3 }; String[] str =newString[] {"黑马程序员", "黑马论坛", "CSDN社区" // 通过Arrays.asList方法打印出集合的内容 System.out.println(Arrays.asList(arr)); // 结果:[[I@62bc184] //原因是因为JDK1.4中为Arrays.asList(Object[] a),JDK1中 //Arrays.asList(T... a)。 arr是int[]类型,JDK1.4中的asList方 //法理不了,JDK1.5可以处理。但是JDK1.5将 //int数组整体作为一个参数进行处理。 // 因此最终结果就是将 int[]进行了封装,结果类型也就成了[[I。 System.out.println(Arrays.asList(str)); // 结果:[a, b, c] };
相关文章推荐
- 阿里算法工程师内推面试经历
- 面试之jsp、Servlet相关知识——生命周期, 区别等
- 黑马程序员——走进面向对象
- 黑马程序员---iOS基础---面向对象编程思想
- 学习与职业规划——机器学习的学习路径和职业规划(简单版)
- 工作小记(一)----面试总结
- 黑马程序员------OC ARC管理和Category
- 黑马程序员——String类
- (剑指Offer)面试题52:构建乘积数组
- 面试准备---Java异常
- 剑指offer面试题36数组中的逆序对数
- 剑指Offer面试题13(java版):在O(1)时间删除链表节点
- 互联网公司机器学习数据挖掘类的职位面试主要考察哪些?
- 面试准备--JAVA集合框架
- (剑指Offer)面试题51:数组中重复的数字
- 数据挖掘工程师面试指南
- 黑马程序员---iOS基础---OC的开始
- 剑指Offer面试题12(Java版):打印1到最大的n位数
- (剑指Offer)面试题50:树中两个结点的最低公共祖先
- 程序员学英语--毕业后的第一个月