黑马程序员--反射(重要)

来源:互联网 发布:图片软件下载 编辑:程序博客网 时间:2024/04/26 22:13

----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

因为反射这一块我的笔记做的很好,就写在源码里面了。。

个人看起来感觉很方便,如果单独抽出来反而看起来很不爽。

package day01;import java.util.Arrays;import java.util.Date;/** * 很重要的一个知识:反射 * @author wangyang * 反射就是把Java类中的各种成分映射成相应的java类。 * 反射不是jdk1.5的新特性。 * 反射会使程序的性能严重下降。 * Class类代表了各个Java类。它的实例对象是各个类在内存中的二进制码。 * 例如:Person类的字节码。Date类的字节码。 * 1.如何得到Class类的实例对象呢? *   有三种方法。 * 2.九种预定义的Class对象。 *  八种基本数据类型,和void。它们的字节码对象不用创建。 * 3.数组类型的Class对象。 *    * */public class ClassDemo{private Date birthday = new Date();public Date getBirthday(){return birthday;}public void setBirthday(Date birthday){this.birthday = birthday;}private int x ;private int y;private String a;private String b;private String c;public ClassDemo(String a, String b, String c)// 这个构造方法是因为ClassDemo2中的练习而创建的。{super();this.a = a;this.b = b;this.c = c;}public int getX(){return x;}public void setX(int x){this.x = x;}public int getY(){return y;}public void setY(int y){this.y = y;}@Overridepublic String toString(){return "ClassDemo [a=" + a + ", b=" + b + ", c=" + c + "]";}public ClassDemo(int x, int y)//这个构造方法是因为ClassDemo2中的练习而创建的。{super();this.x = x;this.y = y;}public ClassDemo(){// TODO Auto-generated constructor stub}public static void main(String[] args) throws Exception{//demo_1();//demo_2();System.out.println(Arrays.asList(args));//用于ClassDemo2的练习。}private static void demo_1() throws Exception//如何得到Class的实例对象呢?{Class<String> c1 = String.class;//这是第一种方法。@SuppressWarnings("unchecked")Class<String> c2 = (Class<String>) new String().getClass();//用对象调用getClass()。这个方法定义在Object里面的。//这种方法得到Class的实例对象是最常用的。从配置文件中读取一个字符串,传递给forName()这个方法。Class<?> c3 = Class.forName("java.lang.String");//使用Class的静态方法。返回一个Class实例对象。此方法会抛出异常。System.out.println(c1==c2);//都是同一个对象。System.out.println(c1==c3);}private static void demo_2()//基本数据类型的Class。{Class<Integer> i = int.class;  //它和Integer.class是不同的。Class<Integer> i2 = Integer.class;System.out.println("int.class==Integer.class:  "+(i==i2));System.out.println("i.isPrimitive():  "+i.isPrimitive());System.out.println("i==Integer.TYPE:  "+(i==Integer.TYPE));//基本数据类型包装类,有一个常量,TYPE可以返回一个属性是基本数据类型的Class对象System.out.println("int[].class.isArray():  "+int[].class.isArray());//数组类型的Class实例对象。}}

package day01;import java.lang.reflect.AccessibleObject;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.util.Arrays;/** * 反射 * @author wangyang * 反射一个类的构造函数。constructor *   要注意的是,当返回构造函数对象的时候,需要的参数是class的对象。 *   当返回的是构造函数生成的对象时。需要的是这个对象的构造函数的参数。 *    * 反射一个类的成员变量。field *    反射成员变量时,就算是私有的也可以访问。 *    不过既然私有就是不想让人访问,还是不访问的好。 *    作业:将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的"b"改成"a"。 *     * 反射一个类的方法。method *    注意的是。如果一个方法的参数是数组的话,invoke方法会自动拆包。 *    所以要在数组前要加上一个(Object),告诉编译器,这是一个参数。不是一堆参数。 *  * 反射一个类的包。package *  * 反射一个数组。array *    */public class ClassDemo2{public static void main(String[] args) throws Exception{//demo_1();//demo_2();//demo_3();//demo_4();//demo_5();demo_6();}private static void demo_6()//反射一个数组。{int[] i1 = new int[]{1,2,3};int[] i2 = new int[4];String[] s1 = new String[]{"a","b","c"};int[][] i3 = new int[3][];System.out.println(i1.getClass()==i2.getClass());//同一个类型号的数组,同一种维度。它们的Class对象相同System.out.println(i3.getClass().getName());//同一个类型号的数组,同一种维度。它们的Class对象相同,否则不同System.out.println(s1.getClass().getName());//同一个类型号的数组,同一种维度。它们的Class对象相同,否则不同System.out.println(i1.getClass().getSuperclass());//每个数组的父类都是Object.//Object[] o1 = i1;//是错误的,因为int不是Object的。Object[] o2 = s1;//是对的。因为String是Objectr的。Object[] o3 = i3;//是对的。因为数组是Object的。//深入解析Array.asList()方法;System.out.println(Arrays.asList(i1));//得到一个结论,基本数据类型的数组是一个Object的子类。不是Object[]。System.out.println(Arrays.asList(s1));}private static void demo_5() throws Exception//反射一个类的main方法。{Class c1 = new ClassDemo().getClass();Method main = c1.getMethod("main", String[].class);main.invoke(null,(Object)new String[]{"abc","wang","yang"});//值得注意是的。如果传入的是一个数组,记得强转成一个Object,因为jdk1.4之前,没有可变参数。//这个地方传入的是一个数组。它就会自动拆包,解析成多个参数。}private static void demo_4() throws Exception//反射一个类的成员方法。{String str1 = "abc";//通过对象获取对象的Class对象,再调用getMethod方法,返回一个指定的Method对象。Method mothod = str1.getClass().getMethod("charAt", int.class);//用指定的Method对象的invoke方法。传入一个对象,一个参数(参数是数组的时候有点不同),返回一个值,这个会值是Object类型的。char s =  (Character) mothod.invoke(str1, 2);System.out.println(s);}private static void demo_3()throws Exception//反射一个成员变量的练习。{ClassDemo cd = new ClassDemo("ball","basketball","itcast");System.out.println(cd);//先打印一下成员变量的值。Field[] fieldabc = cd.getClass().getDeclaredFields();AccessibleObject.setAccessible(fieldabc, true);for(Field field : fieldabc){if(field.getType()==String.class){String str = (String) field.get(cd);str = str.replace("b","c");field.set(cd, str);}}System.out.println(cd);//打印修改后成员变量的值。}private static void demo_2() throws Exception//反射一个成员变量。{ClassDemo cd = new ClassDemo(3,6);//通过对象获得对应的Class对象。再获取指定的成员变量对象。注意的是:获取的不是成员变量的值。Field fieldx = cd.getClass().getDeclaredField("x");//如果要访问类中私有的成员变量,就要用下面这步,暴力反射。fieldx.setAccessible(true);//获取指定对象对应的这个成员变量的值。。注意:返回的是object。int x = (Integer)fieldx.get(cd);System.out.println(x);}private static void demo_1() throws Exception//反射一个Class对象的构造函数。{// 反射一个String的构造函数。记得加泛型。Constructor<String> constructor1 = String.class.getConstructor(StringBuffer.class);//这个方法的参数是可变参数。//通过String的构造函数(其中的参数已经确定)创建一个String对象。String str = constructor1.newInstance(new StringBuffer("123"));System.out.println(str);//创建无参的对象。可以用Class类中的newInstance方法。str = String.class.newInstance();}}
package day01;import java.io.FileInputStream;import java.io.InputStream;import java.util.Collection;import java.util.Properties;/**反射的最重要的应用: *  * 框架: * 什么是框架呢? * ex:我做房子卖给用户住,由用户自己安装门窗和空调, *    我做的房子就是框架,用户需要使用我的框架,把门窗插入进我提供的框架中。 *    框架与工具类有区别,工具类被用户的类调用,而框架则是调用用户提供的类。 *     * 加载资源文件的方式: * java加载资源文件是从用户当前活动目录加载的。 * ex:C:\Users\wangyang>  这个目录就是当前活动目录。 *    F:\>  这个目录就是当前活动目录。你进入哪个目录,哪个就是当前活动目录。 *  * 1.getRealPath:\金山\配置文件。 *  这是第一种。先拿到金山的目录。再拿到配置文件的目录。 *   * 2.类加载器。 *  主要作用。加载类文件。在指定的classpath目录加载类文件,同时还可以加载配置文件。 *  ClassDemo3.Class.getClassLoader().getResourceAsStream("java0917\config.properties"); *  返回的是InputStream();只有读文件的功能。 *   * 3.Class的方法。 *  相当于简化了类加载器。 *  ClassDemo3.Class.getResourceAsStream("config.properties"); *  返回的也是InputStream();只能读文件。这个方法的参数,不用指定目录。更聪明。 *   * @author wangyang * 利用反射,自己做一个很小的框架。 * 把用户要指定的集合存在一个文件中。 *  * 这个例子很好。 */public class ClassDemo3{public static void main(String[] args) throws Exception{/** * 第一步:把配置文件加入内存。 *///InputStream is = new FileInputStream("config.properties");//这是一种,把配置文件放在活动目录下。//InputStream is = ClassDemo3.class.getClassLoader().getResourceAsStream("java0917\\config.properties");//这是用类加载器。把配置文件放在classpath路径下。InputStream is = ClassDemo3.class.getResourceAsStream("config.properties");//这是用Class的方法。Properties pro = new Properties();pro.load(is);is.close();/** * 第二步:把配置文件变成具体的类。 */String classname = (String) pro.get("classname");@SuppressWarnings("unchecked")Collection<Demo> collection = (Collection<Demo>) Class.forName(classname).newInstance();/** * 第三步:使用这个类。 */Demo d1 = new Demo(1,1);Demo d2 = new Demo(2,2);Demo d3 = new Demo(1,1);collection.add(d1);collection.add(d2);collection.add(d3);System.out.println(collection.size());}}

下面这个是配置文件config.properties
classname=java.util.HashSet



----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

0 0
原创粉丝点击