------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
反射的基石->Class类事物
Java程序中各个Java类属于同一类事物,描述这类事物的Java类名就是Class
如何得到各个字节码对应的实例对象(Class类型)
类名.class
如何得到各个自己吗对应的实例对象(Class 类型)
类名.class 例如 System.class
对象.getClass(),例如System.class
对象.getClass(),liru ,new Date.getClass();
Class.forName("") 例如 Class.forname("java.util.Date");
9个预定义Class实例对象
八个基本类型加一个void类型
在源程序中穿线的类型都有各自的Class实例对象,例如int[],void
反射就是把Java类中的各种成分映射成相应的java类
Constructor
Constructor类代表某个类中的一个构造方法
得到某个类所有的构造方法
例子:Construct constructors[]= Class.forName("java.lang.String").getConstructors()
得到某一个的构造方法
例子: Construct constructor = Class.forName("java.lang.String").getConstructor(StringBuffer("abc"))
创建实例对象:
通常方式:String str = new String(new StringBuffer("abc"));
反射方式: String str = (Str)constructor.newInstance(new StringBuffer("abc"));
调用获得的方法是要用到上面相同的实例对象。
Class.newInstance()方法
例子: String obj=(String)Class.forName("java.lang.String").newInstance();
该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
用了缓存机制来保存默认的构造方法实例对象
Field 类
Field类代表某个类中的一个成员变量
演示用eclipse自动生成java类的构造方法
Filed对象时对应类上面的成员变量,类只有一个,而该类的实例对象有有多个,所以字段field代表的是变量的定义,而不是具体的变量
private和public所用的方法不同。 x(public) y (private);
- <pre name="code" class="java"> Student stu = new Student(2,3);
- Field fieldx = stu.getClass().getDeclaredField("x");
- System.out.println(fieldx.get(stu));
- Field fieldy = stu.getClass().getDeclaredField("y");
- fieldy.setAccessible(true);//私有属性要写这个允许访问的方法,才能获取字段信息。
- System.out.println(fieldy.getInt(stu));
写一个程序,这个程序能够根据用户提供的类名,去执行类中main方法
启动Java程序的main方法的参数是一个字符串数组,即public static voidmain
(String []args),通过反射方式来调用这个main方法按jdk1.5的语法,这个数组是一个参数,而按jdk1.4的语法,数组中的每一个元素对应一个参数,当把一个字符串数组作为参数传递个invoke方法是,javac到底会按照那种语法进行处理呢?jdk1.5
要兼容jdk1.4的预压,会按jdk1.4的语法进行处理,即把数组打散成若干个
单独的参数,所以在给main方法纯笛参数时,不能使用代码mainMethod.invoke
(null, new String[] {“xxx”}); javac 只会把它当做jdk1.4的语法进行理解,而不把它当做jdk1.5的语法解释,因此会出现参数类型不对的问题
解决办法
method.invoke(null, new String[]{"XXX"});method.invoke(null, (Object)new String[]{"XXX"});
Method 类
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对象应用的是一个静态方法。
具有相同唯数和元素类型的数组属于同一个类型,即具有相同Class实例对象。
代表数组的Class实例对象getSuperClass()方法放回父类为Object类对应的Class
基本类型的一唯数组可以被当做Object类型使用。不能当做Object[]类型使用;
非基本类型的一唯数组,既可以当做Object类型使用,有可以当做Objcet{]
类型使用。Arrays.asList()方法处理(int[] 和String[] 时的差异).
扩展:
数组也是一个类,基本数据类型不是一个类
int [][] a3 = new int[2][3];
Object [] obj = a3;
框架与框架要解决的核心问题
我做房子卖给用户住,由用户自己安装门窗和空调,我做的房子就是框架,用户需要使用我的框架,把门窗插入进我提供的框架中,框架与工具类有区别,工具类被用户的类调用,而框架则是调用用户提供的类
框架要解决的核心问题
因为在写程序时,无法知道要被调用的类名,所以,在程序中无法直接new某个类的实例对象,而要用反射方式来做。
记住,要用完整的路径了,完整的路径不是硬编码,而是运算出来的
可以将配置文件放工程下
- public static void main(String[] args) throws Exception {
- // TODO Auto-generated method stub
- // TODO Auto-generated methodstub
- InputStream is = new FileInputStream("configure.properties");
- Properties pro = new Properties();
- pro.load(is);//加载文件
- is.close();//关闭字节流
- String classpath = pro.getProperty("className");
- System.out.println("classpath="+classpath);
- Collection coll = (Collection)Class.forName(classpath).newInstance();//实例化对象
- coll.add("it");
- coll.add("caocao");
- System.out.println(coll.size());
- }
- }
用类加载器加载配置文件,放在classpath路径下
Reflectsec.class.getClassLoader().getResourceAsStream("baidu/com/sec/configure.properties");
Reflectsec.class.getResourceAsStream("configure.properties");
可以得到Reflectsec的包路径,这个配置文件就在包下