《黑马程序员》反射机制《一》
来源:互联网 发布:数据库开发软件 编辑:程序博客网 时间:2024/06/05 00:59
------- android培训、java培训、期待与您交流! ----------
/**
* 第十七集 透彻分析反射的基础Class类
* 反射的基石--》Class类
* Java程序中的各个Java类属于同一事物,描述这类事物的java类名就是Class
* 对比提问:众多的人用一个什么类来表示?众多的Java类用什么来表示?
* 人————>Person
* java————>Class
* 对比提问:Person类代表人,他的实例就像是张三,李四这样一个个具体的人,
* Class类代表java类,它的各个具体对象有分别是什么呢?
* --对应各个类在内存中的字节码,例如,Preson类的字节码,ArrayList类的字节码,等等。
* --一个类被类加载器加载到内存中,占用一篇储存空间,这个空间里面的内容就是类的字节码
* 不同的类的字节码是不同的,所以他们在内存中的内容量是不同的,这一个个空间可分别用一个个的
* 对象来表示,这些对象显然具有相同的类型,这个类型是什么呢?
* 如何得到各个字节码的实例对象类(Class类型)
* --类名.class,例如,System.class
* 对象.getClass(),例如,new Date().getClass()
* Class.forName("类名"),例如,Class.forName("java.util.Date").
* 九个预定义Class实例对象:
* --参看Class.isPrivate方法的帮助
* int.class==Integer.TYPE
* 数组类型的Class实例对象
* --Class。isArray()
* 总之,只要是在源程序中出现的类型,都有各自的Class实力类型,例如,int[].void
*
*
*
* Java类是用于描述一个事物的共性,该类事物有什么属性,没什么属性,至于这个属性的值是什么
* 则是由这个类的实例对象来确定的,不同的实例对象有不同的属性值。java程序中的各个java类
* 他们是否属于同一类事物,是不是可以用一个类来描述这类事物呢?这个类的名字就是Class
* 要注意鱼小邪class关键字的区别哦。Class类描述了哪些方面的信息?类的名字,类的访问属性,
* 类的所属的包名,字段名称的列表,方法名称,等等。
* 学习反射,首先要明白Class这个类
*/
/**
*第十八集 理解反射的概念
*
* 一个学生总结的很精辟
* “反射就是把JAVA类中的各个成分映射成相应的java类”。这句话比很多书上讲解得都透彻,都精辟
* 反射就是把java类中各种成分映射成相应的java类。
* 例如,一个java类中用一个Class类的对象来表示,一个类中组成部分成员变量,方法
* 构造方法,包等等信息也用一个个的java类来表示,就像汽车是个类,汽车中的发动机,
* 变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列的方法,来获得
* 其中的变量,方法
*
* @author Administrator
*
*/
/**
* 第十九集
* 一个Class代表一个字节码,一个Method代表一个字节码里面的方法
* Constructor类代表某个类中的一个构造方法
* 得到某个类所有的构造方法
* --例子:Constructor[] construtors=
* Class.forName("java.lang.String").getConstructor();
* 得到某一个构造方法
* --例子: Constructor constructor =
* Class.forName("java.lang.String").getConstructor(StringBuffer.class)
* --获得党发的时候要用到类型
* 创建实例对象
* --通常方式:String str = new String(new StringBuffer("abc"));
* --反射方式:String str = (String)constructor.newinstance(new StringBuffer("abc"));
* --调用方法的时候要用到上面相同类型的实例对象
*
* Class.newInstance()方法:
* --例子:String obj = (String)Class.forName("java.lang.String").newInstance();
* --该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
* --该方法内部的具体代码是怎么样写的呢?用到了缓存机制来保存默认构造方法的实例对象
*
* @author Administrator
*
*/
/**
* 第二十集 成员变量的反射
* Field类代表某个类中的一个成员变量
* 演示用eclipse自动生成java类的构造方法
* 问题:得到的Field对象是对应到类上面的成员变量,还是对应到对象上的成员变量?
* 类只有一个,而该类的实例对象有多个,如果是与对象关联,哪关联那个对象呢?
* 所以字段FieldX代表的是x的定义,而不是具体的x的变量。
*
*/
/**
* 第二十一集成员变量反射的综合实例
* 将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的“b”改成“a”;
* changeStringValue(pt1);
* if(field.getType().equals(String.class)){
* 上面这个不爽 用equals语义不准确
* 这个里应该用双等号,都是拿一份同一个字节码,比较字节码应该用双等号
* 改完之后打印出来
* 为了看到改变后的效果,你还有必要覆盖toString方法
*
* @author Administrator
*
*/
/**
* 第二十二集 成员方法的反射
* Method类代表某个类中的一个成员方法
* 得到类中的某一个方法:
* 例子: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.4和1.5的invoke的区别:
* jdk1.5:public Object invoke(Object obj, Object...args)
* jdk1.4:public Object invoke(Object obj,Object[] args),
* 既按jdk1.4的语法,需要将一个数组作为参数传递给invoke方法时,数组中的每个元素分别对应被
*
* @author Administrator
*
*/
/**
* 第二十三集 对接收数组成员方法进行反射 Main
* 用反射方式执行某个类中的main方法
* 目标:
* 写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法
* 问题:
* 启动java程序中的main方法的参数是一个字符串数组,既public static void main(String[] args)
* 通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数
* 而按jdk1.4的语法,数组每一个元素对应一个参数,当把一个字符串数组作为参数传递给jdk1.4的语法时,
* 会按jdk1.4的语法处理,即把数组打散成为若干个单独的参数。所以,再给main方法传递参数时,不能使用代码
* main Method。invoke(null, new String[]{"xxx"}),javac只把它当做jdk1.4的语法进行理解
* 而不把它当做jdk1.5的语法解释,因此会出现参数不对的问题。
* 解决办法:
* --main Method.invoke(null, new Object[]{new String[]{"xxx"}})
* --main Method.invoke(null, Object({new String[]{"xxx"}),编译器会作为特殊处理,编译器编译时
* 不把参数当做数组看待,也就不会把数组打散成若干个参数了
*/
/**
/**
* @param args
* @throws ClassNotFoundException
* @throws NoSuchMethodException
* @throws SecurityException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws IllegalArgumentException
* @throws NoSuchFieldException
*/
public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchFieldException {
// TODO Auto-generated method stub
String str1 = "abc";
/**
* str1是字符串对象,str1.getClass()就是得到String它的字节码
*/
Class cls1 = str1.getClass();
/**
* 这个也是String的字节码
*/
Class cls2 = String.class;
/**
* 也是String的字节码
*/
Class cls3 = Class.forName("java.lang.String");
System.out.println(cls1 == cls2);
System.out.println(cls1 == cls3);
/**
* 是否是原始类型
* String并不是基本类型,虽然经常用,它是一个类
*/
System.out.println(cls1.isPrimitive());
/**
* int它的字节码是一个基本的类型
*/
System.out.println(int.class.isPrimitive());
/**
* Integer是一个包装类 和int不是一个类型 各有各的字节码
*/
System.out.println(int.class == Integer.class);
/**
* Integer里面专门定义了一个常量叫TYPE,这个TYPE就代表
* 包装类所包装的基本的类型的字节码。
*/
System.out.println(int.class == Integer.TYPE);
/**
* 数组是一个类型但不是原始类型
*/
System.out.println(int[].class.isPrimitive());
/**
* 可变参数,可以传一个也可以传两个
* 参数是数组Class[]
* new String(new StringBuffer("abc"))
* Constructor代表的是一个构造方法
* 得到这个方法的时候需要类型
* 调用这个方法的时候也要传递同样类型的对象
*/
Constructor constructor1 = String.class.getConstructor(StringBuffer.class);
String str2 = (String) constructor1.newInstance(new StringBuffer("abc"));
System.out.println(str2.charAt(2));
ReflectPoint pt1 = new ReflectPoint(3,5);
/**
* fieldY的值是多少?是5,错!
* fieldY不是对象身上的变量,而是类上,要用它去取某个对象上对应的值
*/
Field fieldY = pt1.getClass().getField("y");
System.out.println(fieldY.get(pt1));
/**
* getDeclaredField()无论可见不可见都能够取出来
*/
Field fieldX = pt1.getClass().getDeclaredField("x");
/**
* 设置说可以访问 暴力反射
* 出了两个错误,上面说看不见,下面是拿不到
*/
fieldX.setAccessible(true);
System.out.println(fieldX.get(pt1));
changeStringValue(pt1);
/**
* 改完之后打印出来
* 为了看到改变后的效果,你还有必要覆盖toString方法
*/
System.out.println("behind change----"+ pt1);
/**
* 这个方法接受两个参数,第一个参数方法名字,这个类身上有多个方法,确定是哪个方法
* 第二个参数是,一个类里面的方法有多种重载形式,选取哪一种呢?
* str1.charAt(1);
* invoke 调用这个方法
*
*/
Method methodCharAt = String.class.getMethod("charAt", int.class);
System.out.println("method---"+methodCharAt.invoke(str1, 1));
System.out.println("method--"+methodCharAt.invoke(str1, new Object[]{2}));
/**
* 这就是用静态代码的方式直接调用它的方法
* 普通方式调完后,为甚么要用反射的方式调用
*/
//TestArguments.main(new String[]{"111","222","333"});
String startingClassName = args[0];
Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
/**
* 因为main是静态方法,第一个参数是null
* 本是数组把多个元素打包成一个数组元素,但是java不把数组当做一个元素
* 而是打开分别作为多个参数
* 所以再打一个包Object[],在object数组中装的第一个元素是数组
* 每个数组的父类都是Object
* 如果在前面加Object对其转换就是对编译器说我给你的是一个对象,不要拆包
* mainMethod.invoke(null,(Object)new String[]{"111","222","333"});
* 等于在外面运行这个类
* run as --> run configurations -->Arguments
* 导入cn.itcast.day1.TestArguments
*/
mainMethod.invoke(null,new Object[]{new String[]{"111","222","333"}});
int [] a1 = new int[3];
int [] a2 = new int[4];
int[][] a3 = new int[2][3];
String [] a4 = new String[3];
/**
* 对象要得到字节码要用方法
* Incompatible 不相容 矛盾 不能同时成立
* operand 操作数运算数
* capture 捕获
*/
System.out.println(a1.getClass() == a2.getClass());
//System.out.println(a1.getClass() == a4.getClass());
//System.out.println(a1.getClass() == a3.getClass());
/**
* 得到结果[I中括号代表数组,I代表整数
*/
System.out.println(a1.getClass().getName());
System.out.println(a1.getClass().getSuperclass().getName());
System.out.println(a4.getClass().getSuperclass().getName());
Object aObj1 = a1;
Object aObj2 = a2;
//Object[] aObj3 = a1;
Object[] aObj4 = a3;
Object[] aObj5 = a4;
System.out.println(a1);
System.out.println(a4);
System.out.println(Arrays.asList(a1));
System.out.println(Arrays.asList(a4));
System.out.println();
Object obj = null;
printObject(a4);
printObject("xyz");
}
/**
* 你给我一个Object我就把他打印出来,
* @param obj
*/
private static void printObject(Object obj) {
Class clazz = obj.getClass();
if(clazz.isArray()){
int len = Array.getLength(obj);
for(int i=0;i<len;i++){
System.out.println(Array.get(obj, i));
}
}else{
System.out.println(obj);
}
}
/**
* 这个程序写明白了,说不懂反射,谁相信呢?
* 好好看看本程序!
* @param obj
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
private static void changeStringValue(Object obj) throws IllegalArgumentException, IllegalAccessException {
Field[] fields = obj.getClass().getFields();
for(Field field : fields){
/**
* if(field.getType().equals(String.class)){
* 上面这个不爽 用equals语义不准确
* 这个里应该用双等号,都是拿一份同一个字节码,比较字节码应该用双等号*
*/
if(field.getType()== String.class){
String oldValue = (String)field.get(obj);
/**
* 将字符串里面的b换成a
*/
String newValue = oldValue.replace('b', 'a');
/**
* 拿到之后还要设置进去
*/
field.set(obj, newValue);
}
}
}
}
class TestArguments{
public static void main(String[] args){
for(String arg : args){
System.out.println(arg);
}
}
}
------- android培训、java培训、期待与您交流! ----------
/**
* 第十七集 透彻分析反射的基础Class类
* 反射的基石--》Class类
* Java程序中的各个Java类属于同一事物,描述这类事物的java类名就是Class
* 对比提问:众多的人用一个什么类来表示?众多的Java类用什么来表示?
* 人————>Person
* java————>Class
* 对比提问:Person类代表人,他的实例就像是张三,李四这样一个个具体的人,
* Class类代表java类,它的各个具体对象有分别是什么呢?
* --对应各个类在内存中的字节码,例如,Preson类的字节码,ArrayList类的字节码,等等。
* --一个类被类加载器加载到内存中,占用一篇储存空间,这个空间里面的内容就是类的字节码
* 不同的类的字节码是不同的,所以他们在内存中的内容量是不同的,这一个个空间可分别用一个个的
* 对象来表示,这些对象显然具有相同的类型,这个类型是什么呢?
* 如何得到各个字节码的实例对象类(Class类型)
* --类名.class,例如,System.class
* 对象.getClass(),例如,new Date().getClass()
* Class.forName("类名"),例如,Class.forName("java.util.Date").
* 九个预定义Class实例对象:
* --参看Class.isPrivate方法的帮助
* int.class==Integer.TYPE
* 数组类型的Class实例对象
* --Class。isArray()
* 总之,只要是在源程序中出现的类型,都有各自的Class实力类型,例如,int[].void
*
*
*
* Java类是用于描述一个事物的共性,该类事物有什么属性,没什么属性,至于这个属性的值是什么
* 则是由这个类的实例对象来确定的,不同的实例对象有不同的属性值。java程序中的各个java类
* 他们是否属于同一类事物,是不是可以用一个类来描述这类事物呢?这个类的名字就是Class
* 要注意鱼小邪class关键字的区别哦。Class类描述了哪些方面的信息?类的名字,类的访问属性,
* 类的所属的包名,字段名称的列表,方法名称,等等。
* 学习反射,首先要明白Class这个类
*/
/**
*第十八集 理解反射的概念
*
* 一个学生总结的很精辟
* “反射就是把JAVA类中的各个成分映射成相应的java类”。这句话比很多书上讲解得都透彻,都精辟
* 反射就是把java类中各种成分映射成相应的java类。
* 例如,一个java类中用一个Class类的对象来表示,一个类中组成部分成员变量,方法
* 构造方法,包等等信息也用一个个的java类来表示,就像汽车是个类,汽车中的发动机,
* 变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列的方法,来获得
* 其中的变量,方法
*
* @author Administrator
*
*/
/**
* 第十九集
* 一个Class代表一个字节码,一个Method代表一个字节码里面的方法
* Constructor类代表某个类中的一个构造方法
* 得到某个类所有的构造方法
* --例子:Constructor[] construtors=
* Class.forName("java.lang.String").getConstructor();
* 得到某一个构造方法
* --例子: Constructor constructor =
* Class.forName("java.lang.String").getConstructor(StringBuffer.class)
* --获得党发的时候要用到类型
* 创建实例对象
* --通常方式:String str = new String(new StringBuffer("abc"));
* --反射方式:String str = (String)constructor.newinstance(new StringBuffer("abc"));
* --调用方法的时候要用到上面相同类型的实例对象
*
* Class.newInstance()方法:
* --例子:String obj = (String)Class.forName("java.lang.String").newInstance();
* --该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
* --该方法内部的具体代码是怎么样写的呢?用到了缓存机制来保存默认构造方法的实例对象
*
* @author Administrator
*
*/
/**
* 第二十集 成员变量的反射
* Field类代表某个类中的一个成员变量
* 演示用eclipse自动生成java类的构造方法
* 问题:得到的Field对象是对应到类上面的成员变量,还是对应到对象上的成员变量?
* 类只有一个,而该类的实例对象有多个,如果是与对象关联,哪关联那个对象呢?
* 所以字段FieldX代表的是x的定义,而不是具体的x的变量。
*
*/
/**
* 第二十一集成员变量反射的综合实例
* 将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的“b”改成“a”;
* changeStringValue(pt1);
* if(field.getType().equals(String.class)){
* 上面这个不爽 用equals语义不准确
* 这个里应该用双等号,都是拿一份同一个字节码,比较字节码应该用双等号
* 改完之后打印出来
* 为了看到改变后的效果,你还有必要覆盖toString方法
*
* @author Administrator
*
*/
/**
* 第二十二集 成员方法的反射
* Method类代表某个类中的一个成员方法
* 得到类中的某一个方法:
* 例子: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.4和1.5的invoke的区别:
* jdk1.5:public Object invoke(Object obj, Object...args)
* jdk1.4:public Object invoke(Object obj,Object[] args),
* 既按jdk1.4的语法,需要将一个数组作为参数传递给invoke方法时,数组中的每个元素分别对应被
*
* @author Administrator
*
*/
/**
* 第二十三集 对接收数组成员方法进行反射 Main
* 用反射方式执行某个类中的main方法
* 目标:
* 写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法
* 问题:
* 启动java程序中的main方法的参数是一个字符串数组,既public static void main(String[] args)
* 通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数
* 而按jdk1.4的语法,数组每一个元素对应一个参数,当把一个字符串数组作为参数传递给jdk1.4的语法时,
* 会按jdk1.4的语法处理,即把数组打散成为若干个单独的参数。所以,再给main方法传递参数时,不能使用代码
* main Method。invoke(null, new String[]{"xxx"}),javac只把它当做jdk1.4的语法进行理解
* 而不把它当做jdk1.5的语法解释,因此会出现参数不对的问题。
* 解决办法:
* --main Method.invoke(null, new Object[]{new String[]{"xxx"}})
* --main Method.invoke(null, Object({new String[]{"xxx"}),编译器会作为特殊处理,编译器编译时
* 不把参数当做数组看待,也就不会把数组打散成若干个参数了
*/
/**
* 第二十四集 数组与Object的更关系及反射类型
/**
* 第二十五集 数组的反射及应用
* 具有相同维数和元素的数组属于同一类型,即具有相同的Class实例对象。
* 代表数组的Class实例对象的getSuperClass()方法返回父类为Object类对应的Class。
* 基本类型的一维数组可以被当做Object类型使用,不能当做Object[]类型使用;
* 非基本类型的一位数组,既可以当做Object类型,又可以当做Object类型使用。
* Arrays.asList()方法处理int[]和String[]时的差异
* Array工具用于完成对数组的反射操作。
* 思考题:怎么得到数组中的元素类型?
*
*/
package cn.itcast.day1;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* @param args
* @throws ClassNotFoundException
* @throws NoSuchMethodException
* @throws SecurityException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws IllegalArgumentException
* @throws NoSuchFieldException
*/
public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchFieldException {
// TODO Auto-generated method stub
String str1 = "abc";
/**
* str1是字符串对象,str1.getClass()就是得到String它的字节码
*/
Class cls1 = str1.getClass();
/**
* 这个也是String的字节码
*/
Class cls2 = String.class;
/**
* 也是String的字节码
*/
Class cls3 = Class.forName("java.lang.String");
System.out.println(cls1 == cls2);
System.out.println(cls1 == cls3);
/**
* 是否是原始类型
* String并不是基本类型,虽然经常用,它是一个类
*/
System.out.println(cls1.isPrimitive());
/**
* int它的字节码是一个基本的类型
*/
System.out.println(int.class.isPrimitive());
/**
* Integer是一个包装类 和int不是一个类型 各有各的字节码
*/
System.out.println(int.class == Integer.class);
/**
* Integer里面专门定义了一个常量叫TYPE,这个TYPE就代表
* 包装类所包装的基本的类型的字节码。
*/
System.out.println(int.class == Integer.TYPE);
/**
* 数组是一个类型但不是原始类型
*/
System.out.println(int[].class.isPrimitive());
/**
* 可变参数,可以传一个也可以传两个
* 参数是数组Class[]
* new String(new StringBuffer("abc"))
* Constructor代表的是一个构造方法
* 得到这个方法的时候需要类型
* 调用这个方法的时候也要传递同样类型的对象
*/
Constructor constructor1 = String.class.getConstructor(StringBuffer.class);
String str2 = (String) constructor1.newInstance(new StringBuffer("abc"));
System.out.println(str2.charAt(2));
ReflectPoint pt1 = new ReflectPoint(3,5);
/**
* fieldY的值是多少?是5,错!
* fieldY不是对象身上的变量,而是类上,要用它去取某个对象上对应的值
*/
Field fieldY = pt1.getClass().getField("y");
System.out.println(fieldY.get(pt1));
/**
* getDeclaredField()无论可见不可见都能够取出来
*/
Field fieldX = pt1.getClass().getDeclaredField("x");
/**
* 设置说可以访问 暴力反射
* 出了两个错误,上面说看不见,下面是拿不到
*/
fieldX.setAccessible(true);
System.out.println(fieldX.get(pt1));
changeStringValue(pt1);
/**
* 改完之后打印出来
* 为了看到改变后的效果,你还有必要覆盖toString方法
*/
System.out.println("behind change----"+ pt1);
/**
* 这个方法接受两个参数,第一个参数方法名字,这个类身上有多个方法,确定是哪个方法
* 第二个参数是,一个类里面的方法有多种重载形式,选取哪一种呢?
* str1.charAt(1);
* invoke 调用这个方法
*
*/
Method methodCharAt = String.class.getMethod("charAt", int.class);
System.out.println("method---"+methodCharAt.invoke(str1, 1));
System.out.println("method--"+methodCharAt.invoke(str1, new Object[]{2}));
/**
* 这就是用静态代码的方式直接调用它的方法
* 普通方式调完后,为甚么要用反射的方式调用
*/
//TestArguments.main(new String[]{"111","222","333"});
String startingClassName = args[0];
Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
/**
* 因为main是静态方法,第一个参数是null
* 本是数组把多个元素打包成一个数组元素,但是java不把数组当做一个元素
* 而是打开分别作为多个参数
* 所以再打一个包Object[],在object数组中装的第一个元素是数组
* 每个数组的父类都是Object
* 如果在前面加Object对其转换就是对编译器说我给你的是一个对象,不要拆包
* mainMethod.invoke(null,(Object)new String[]{"111","222","333"});
* 等于在外面运行这个类
* run as --> run configurations -->Arguments
* 导入cn.itcast.day1.TestArguments
*/
mainMethod.invoke(null,new Object[]{new String[]{"111","222","333"}});
int [] a1 = new int[3];
int [] a2 = new int[4];
int[][] a3 = new int[2][3];
String [] a4 = new String[3];
/**
* 对象要得到字节码要用方法
* Incompatible 不相容 矛盾 不能同时成立
* operand 操作数运算数
* capture 捕获
*/
System.out.println(a1.getClass() == a2.getClass());
//System.out.println(a1.getClass() == a4.getClass());
//System.out.println(a1.getClass() == a3.getClass());
/**
* 得到结果[I中括号代表数组,I代表整数
*/
System.out.println(a1.getClass().getName());
System.out.println(a1.getClass().getSuperclass().getName());
System.out.println(a4.getClass().getSuperclass().getName());
Object aObj1 = a1;
Object aObj2 = a2;
//Object[] aObj3 = a1;
Object[] aObj4 = a3;
Object[] aObj5 = a4;
System.out.println(a1);
System.out.println(a4);
System.out.println(Arrays.asList(a1));
System.out.println(Arrays.asList(a4));
System.out.println();
Object obj = null;
printObject(a4);
printObject("xyz");
}
/**
* 你给我一个Object我就把他打印出来,
* @param obj
*/
private static void printObject(Object obj) {
Class clazz = obj.getClass();
if(clazz.isArray()){
int len = Array.getLength(obj);
for(int i=0;i<len;i++){
System.out.println(Array.get(obj, i));
}
}else{
System.out.println(obj);
}
}
/**
* 这个程序写明白了,说不懂反射,谁相信呢?
* 好好看看本程序!
* @param obj
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
private static void changeStringValue(Object obj) throws IllegalArgumentException, IllegalAccessException {
Field[] fields = obj.getClass().getFields();
for(Field field : fields){
/**
* if(field.getType().equals(String.class)){
* 上面这个不爽 用equals语义不准确
* 这个里应该用双等号,都是拿一份同一个字节码,比较字节码应该用双等号*
*/
if(field.getType()== String.class){
String oldValue = (String)field.get(obj);
/**
* 将字符串里面的b换成a
*/
String newValue = oldValue.replace('b', 'a');
/**
* 拿到之后还要设置进去
*/
field.set(obj, newValue);
}
}
}
}
class TestArguments{
public static void main(String[] args){
for(String arg : args){
System.out.println(arg);
}
}
}
------- android培训、java培训、期待与您交流! ----------
0 0
- 《黑马程序员》反射机制《一》
- 黑马程序员---java反射机制(一)
- 黑马程序员_JAVA反射机制(一)
- 黑马程序员 反射机制
- 黑马程序员--反射机制
- 黑马程序员-反射机制
- 【黑马程序员】反射机制
- 黑马程序员 反射机制
- 黑马程序员-反射机制
- 黑马程序员----反射机制
- 黑马程序员 反射机制
- 黑马程序员--反射机制
- 黑马程序员------反射机制
- 黑马程序员------反射机制
- 黑马程序员-反射机制
- 黑马程序员----反射机制
- 黑马程序员-Java反射机制
- 黑马程序员-java反射机制
- uva 607 - Scheduling Lectures
- Android Call requires API level 11 (current min is 8)的解决方案
- 管理处理器的亲和性(affinity)
- 2013年迟来的总结
- MAC下启动python得idle
- 《黑马程序员》反射机制《一》
- 淘宝数据魔方技术架构解析
- 读懂让自己更智慧的10句话
- Ubuntu10.04上apache2: bad user name ${APACHE_RUN_USER}问题解决
- leetcode Count and Say 2.13 难度系数2
- Spring RMI源码解读
- qt 布局
- 《黑马程序员》反射机制(二)与内省
- leetcode JAVA Unique Paths 2.14 难度系数2