Java高新技术:反射
来源:互联网 发布:手机淘宝申请售后不了 编辑:程序博客网 时间:2024/05/21 18:37
Class类是反射的基石,而java中各个java类也是属于同一类事物。而这类事物就是Class类
(平时定义类都是用class,注意这里小写和Class类的大写)
错误的赋值:Class cs=new Class();
正确的赋值:Class cs2=Date.class;
字节码:当一个类(二进制程序)被类加载器加载到内存中,会占用一部分内存空间,这部分空间的内容就叫做字节码;
不同的类字节码是不同的,所以在内存空间的内容是不同的,这一个个内存空间可分别用一个个对象来表示。
获取各个字节码对应的实例对象的三种方法:
(1)类名.class
(2)对象.getClass()
(3)Class.forName("类名"):返回字节码,java虚拟机还没有字节码,会用类加载器加载,把字节码缓存起来,该方法再返回该字节码
八个基本数据类型,分别对应八个Class对象,另外还有一个void.class
//获取各个字节码对应的实例对象三种方法String string="反射";Class cs1=String.class;Class cs2=string.getClass();Class cs3=Class.forName("java.lang.String");//三个类型对应的字节码是同一份System.out.println(cs1==cs2);//trueSystem.out.println(cs2==cs3);//true//isPrimitive()判断是否是基本类型System.out.println(cs1.isPrimitive());//falseSystem.out.println(int.class.isPrimitive());//trueSystem.out.println(int.class==Integer.class);//falseSystem.out.println(int.class==Integer.TYPE);//trueSystem.out.println(int[].class.isPrimitive());//数组不是原始类型System.out.println(int[].class.isArray());//true
反射概念理解
反射就是把Java类中的各种成分映射成相应的java类
例如,一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示。就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是Field、Method、Contructor、Package等等。
一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象后,得到这些实例对象后有什么用呢?怎么用呢?这正是学习和应用反射的要点。
Constructor类
Constructor类代表某一类的构造方法。获取构造方法:
1)得到这个类的所有构造方法:如得到上面示例中Person类的所有构造方法
Constructor[] cons = Class.forName(“cn.itheima.Person”).getConstructors();
2)获取某一个构造方法:
Constructor con=Person.class.getConstructor(StringBuffer.class);
利用构造方法创建对象:newInstance()
通常方式:String aString=new String(new StringBuffer("hello"));
反射方式:String aString=(String)constructor.newInstance(new StringBuffer("hello"));
注:1.反射导致程序性能下降。
2.注意强制类型转换,因为编译只是检查语法,并不执行,所以并不知道它是String类型的构造函数;
3.对于无参构造函数可以直接利用Class.newInstance()方法;
//反射//constructorString.class.getConstructors();Constructor constructor=String.class.getConstructor(StringBuffer.class);String aString=(String)constructor.newInstance(new StringBuffer("hello"));System.out.println(aString);
Field类
Field代表成员变量;从以下具体例子了解Field类相关知识,ReflecPoint类如下所示:
package com.sf.day1;public class ReflectPoint {private double a;public double b;public String xString="best";public String yString="bad";public String zString="justsoso";public ReflectPoint(double a, double b, String xString, String yString,String zString) {super();this.a = a;this.b = b;this.xString = xString;this.yString = yString;this.zString = zString;}@Override public String toString(){return xString+" "+yString+""+zString;} }注意下面代码中的afield和bfield知识类中的变量,而不是point里的变量,所以必须用Field类变量.get(对象)来获取对象中变量
//filedReflectPoint point=new ReflectPoint(3.0, 4.5,"best","bad","justsoso");Field afield=point.getClass().getDeclaredField("a");//getDeclaredField获取该类中任意成员变量,包括私有Field bfield=point.getClass().getField("b");afield.setAccessible(true);//暴力反射,使得private类型的a可以被访问;System.out.println(afield.get(point));//通过对象afield的get方法获得具体的某对象成员变量的值System.out.println(bfield.get(point));
课堂练习:将对象中的所有String类型的成员变量对应的字符串内容中的字母b改成a
//filed练习//Field xField=point.getClass().getField("xString");//xField.get(point).toString().replace("b", "a");//System.out.println(xField.get(point));//练习Field[] fields=point.getClass().getFields();for(Field field:fields){if(field.getType()==String.class){String oldString=(String)field.get(point);String newString=oldString.replace("b", "a");field.set(point, newString);}}System.out.println(point.toString());
Method类
Method代表成员方法获取Method对象:.getMethod(“方法名”,方法参数类型的字节码)
注:需要方法参数类型这个参数是由于方法重载的存在。
实现此方法所用方法:invoke(对象,参数)
注意:如果是实现某一静态方法,则不需要对象来调用,此时对象位置为null
//MethodMethod method=string.getClass().getMethod("charAt", int.class);System.out.println(method.invoke(string, 1));//调用mainMethod method2=Class.forName(args[0]).getMethod("main", String[].class);method2.invoke(null, (Object)new String[]{"aaa","bbb","ccc"});}}class TestMainMethod{public static void main(String[] args) {for(String arg:args){System.out.println(arg);}
注:实现main的调用要在Run configurations里设置Arguments为com.sf.day1.TestMainMethod;即是此处的args[0];
数组的反射
nt[]数组的名称为:[I
Array工具类用于完成对数组的反射操作:
Array.getLength(Object obj);//获取数组的长度
Array.get(Object obj,int x);//获取数组中的元素
Arrays.asList (List类型) 方法:直接展示改List中所有元素package com.sf.day1;import java.lang.reflect.Array;import java.util.Arrays;public class ArrayRefl {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubint a[]={1,2};int b[]=new int[5];int c[][]=new int[3][4];String d[]=new String[]{"To","Be","No","1"};System.out.println(a.getClass()==b.getClass());//true.注:用等号,没必要用equalsSystem.out.println(a.getClass().getName());// [ISystem.out.println(c.getClass().getName());// [[ISystem.out.println(c.getClass().getSuperclass().getName());//java.lang.ObjectSystem.out.println(d.getClass().getSuperclass().getName());//java.lang.ObjectObject obj1=a;Object obj2=b;Object obj3=c;Object obj4=d;//Object[] obj5=a; //定义错误,a中元素为int类型,注意基本数据类型不是Object//Object[] obj5=b;Object[] obj6=c; //可以,因为c中元素为一位数组,一维数组是ObjectObject[] obj7=d;System.out.println(a);// [I@1db9742System.out.println(Arrays.asList(a));// [[I@1db9742]System.out.println(d); //[Ljava.lang.String;@106d69cSystem.out.println(Arrays.asList(d)); //[To, Be, No, 1]printObj(a);printObj(d);printObj("hehe");}public static void printObj(Object obj) {// TODO Auto-generated method stubif(obj.getClass().isArray()){for(int i=0;i<Array.getLength(obj);i++) {System.out.println(Array.get(obj, i)); //Array.get获取数组元素}}else {System.out.println(obj);}}}
- Java高新技术之反射
- java 高新技术之反射
- java高新技术之反射
- java高新技术—反射
- Java高新技术之反射
- java高新技术:反射
- java高新技术反射
- Java高新技术-反射
- Java 高新技术(反射)
- Java高新技术 反射机制
- java笔记-高新技术-反射
- Java高新技术:反射
- JAVA高新技术---反射总结
- java高新技术:反射
- Java高新技术:反射
- JAVA反射(高新技术)
- Java高新技术 反射机制
- 黑马程序员-Java高新技术-反射
- 关于uva10123
- 我之见--java多线程 ConcurrentHashMap 源码分析
- SVD分词分类的思考
- HDU 3061 最大权闭合图
- Mysql报错:Column count doesn't match value count at row 1
- Java高新技术:反射
- Android之内存管理
- Notepad++使用心得和特色功能介绍
- Lifting the Stone(求任意多边形的重心)
- 【Qt for Android】第一个安卓程序
- “System.Web.UI.Page”不包含“DataItem”的定义,问题的解决
- Hadoop V2.0.3 Cluster Setup Guide
- Python(2.7.x)启动浏览器
- NYOJ38 布线问题(Prim)