列子的话张老师的已经是很不错的啦
这是我总结的张老师的代码你可以看看
String str = "jgsuye";
Class cls1 = str.getClass();//对象调用getClass方法可以得到str所属的类
Class cls2 = String.class;//String类 在内存中的字节码(字节码就是对象)
Class cls3 = Class.forName("java.lang.String");//Class.forName()的作用是返回字节码,有两种方式:
//一是:字节码已经加载在内存中直接返回就行了
//二是:用类加载器加载字节码,缓存在虚拟机中
System.out.println(cls1.isPrimitive());//false,String不是基本数据类型二是一个类
System.out.println(cls1==cls2);//true
System.out.println(cls1==cls3);//true
//说明cls1,cls2,cls3在内存中加载的是同一个字节码
System.out.println(int.class .isPrimitive());//true,说明int是基本类型
System.out.println(int[].class.isPrimitive());//false,数组类型不是原始类型
System.out.println(int.class == Integer.class);//false
System.out.println(int.class == Integer.TYPE );//true
//TYPE是Integer定义的一个常量,其代表包装类型所包装的基本类型的字节码
System.out.println(int[].class.isArray());
//new String(new StringBuffer("ghjs"));
//新建一个StringBuffer对象传给String的构造函数,用如下的反射可以实现相同的效果
Constructor<String> constructor1 = String.class.getConstructor(StringBuffer.class);//给constructor1传递的是StringBuffer的类型
//第一个StringBuffer是选择哪一个构造方法,其中constructor1则是编译形成class文件后,
//在运行等号右半部分执行结果传给constructor1.
//因为运行时才执行String.class.getConstructor(StringBuffer.class),因此在编译期间必须指明constructor1的类型
String str1 = (String)constructor1.newInstance(new StringBuffer("aabbghfs"));
//第二个StringBuffer表示用StringBuffer的同时还传一个StringBffer的对象
System.out.println(str1.charAt(3));//返回指定索引处的 char 值
String str2 = (String)constructor1.newInstance("fdgd");//传的是String类型。
System.out.println(str2.charAt(3));//编译出错,constructor1只能传递StringBuffer的对象
ReflectPoint rp = new ReflectPoint(3,6);//x=3;y=6
//Field fidX = rp.getClass().getField("x");编译报错,x为私有,无权限取到x的字段
Field fidX = rp.getClass().getDeclaredField("x");
//为了得到类上的某个成员变量,必须先得到类的字节码,在通过字节码取得某个字段
//注意fid的值不是6,而是类上字节码的变量,不代表变量上的具体的值;
//fid不是对象身上的变量,要用它去获取某个对象上的值。
fidX.setAccessible(true);//设置可以接受
System.out.println(fidX.get(rp));//通过fidX取到rp的字段
ChangeStringvalue(rp);//调用ChangeStringvalue的方法
System.out.println(rp);
//通过反射得到str1的charAt(1)
Method methodCharAt = String.class.getMethod("charAt",int.class);
//得到String的字节码在得到方法
System.out.println(methodCharAt.invoke(str, 3));
//通过对象调用方法后打印,注意invoke是方法对象上的方法
//如:画圆方法,人,黑板,圆。信息(圆心和半径都是私有的),画圆的方法分配给人,则人要访问员的私有方法不合适
//只有把画圆的动作分配给圆才合适,因为圆有个动作叫“画我”,所有调用的时候如:circle.draw();
//System.out.println(methodCharAt.invoke(null, 3));
//当传递给Method对象的invoke()方法为空null时,说明Method对象对应的是一个静态方法
System.out.println(methodCharAt.invoke(str1, new Object[]{3}));
//TestArguments.main(new String[]{"12","13","22"});//普通方法,根据用户提供的类,去执行该类中的main方法
String StartClassName = args[0];//表示即将启动的类名(现在不知道该类的类名),通过反射的方法来得到类名
Method mainMethod = Class.forName(StartClassName).getMethod("main", String[].class);
mainMethod.invoke(null, new Object []{new String[]{"12","13","22"}});//因为main是静态方法,因此invoke方法不需要传递对象就调用main方法
//new String[]{"12","13","22"}编译时期JDK会把它拆开为三个参数,而invoke只能传递一个参数,因此必须把它打包成一个对象即:new Objetc[]{new String[]{"12","13","22"}}
int [] a1 = new int[3];
int [] a2 = new int[4];
int [][] a3 = new int[2][3];//a3理解为数组a3装在int []数组中
String [] a4 = new String[3];
//每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象
System.out.println(a1.getClass() == a2.getClass());//true
//System.out.println(a1.getClass() == a4.getClass());false元素类型不同
//System.out.println(a1.getClass() == a3.getClass());false数组维数不同
System.out.println(a1.getClass().getName());
System.out.println(a1.getClass().getSuperclass().getName());
System.out.println(a4.getClass().getSuperclass().getName());
Object ob1 = a1;
Object ob2 = a4;
// Object [] ob3 = a1;
Object [] ob4 = a3;//a3是数组中的数组,a3理解为数组a3装在int []数组中,int []是属于Object []的
Object [] ob5 = a4;
System.out.println(a1);
System.out.println(a4);
System.out.println(Arrays.asList(a1));
System.out.println(Arrays.asList(a4));
Object obj = null;
printObject(obj); |