黑马软件工程师——Java基础(26).反射机制
------- http://www.itheima.com" target="blank">android培训a>、java培训a>、期待与您交流! ----------
2015年8月21日星期五
Java基础知识学习(day24)
1, 反射机制:java反射机制是在运动状态中,对于任意一个类(.class文件),都能够知道这个类的所有属性和方法。对于任意一个对象,都能够调动它的任意一个方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称之为java语言的反射机制。
a) 简答理解:能动态获取类中的信息,就是指反射。可以理解为对于类的解剖
2, 如果想要对自定名称的字节码文件进行加载并获取其中的内容并调用其中对应的方法,就可以使用反射技术进行实现。
3, 使用反射技术的好处:很大程度上提高了程序的扩展性
4, Tomcat提供了处理请求和应答的方式。因为具体实现的动作不同。所以对外提供了接口,由开发者完成具体实现。
5, Class类就是使用来描述字节码文件的,该类就可以获取字节码文件中的所有内容。反射就是同该类完成
6, 如何拿到一个类的字节码文件夹?
a) 方法1,Object类中的getClass()方法:想要使用这种方法,必须明确具体的类,并创建对象
b) 方法2,任何数据类型都具备一个静态的属性,.class来获取对应的Class对象。此方法相对简单,但是还是需要明确用到类中的静态成员
c) 方法3,必须掌握。只要通过给定的类的字符串名称就可以获取可以使用Class类中的方法完成,该方法就是forName().这种方法只需要名字即可,更为方便。
7, 当获取指定,名称对应的对象时。该该对象时而该对象时初始化不时空参时的对对象创建方法。
a) 代码演示:
package cn.itcait; import java.lang.reflect.Constructor; /* * 本事来用于演示的是 反射机制中类的获取 * 三种方法: * 1,通过没各类的的方法叫做getClass方法 * 2,通过数据类型都具备的基本属性就是.class获取 * 3,重点:通过Class类中的方法forName()可以直接通过类名的字符串形式即可获取该类的所有方法和内容 * 注意: 在传入字符串时需要带上指定类的包名 */ public class Demo01_Reflect { public static void main(String[] args) throws Exception { //1,通过没各类的的方法叫做getClass方法 Class<? extends Person> class1 = new Person().getClass();//获取指定类的对象 Class<? extends Person> class2 = new Person().getClass(); System.out.println(class1==class2);//输出结果为true,因为这两个对象都来自同一个字节码文件 //2,通过数据类型都具备的基本属性就是.class获取 Class<Person> c1 = Person.class;//获取指定类的对象 Class<Person> c2 = Person.class; System.out.println(c1==c2); //3,重点:通过Class类中的方法forName()可以直接通过类名的字符串形式即可获取该类的所有方法和内容 @SuppressWarnings("unchecked") Class<Person> class3 =(Class<Person>) Class.forName("cn.itcait.Person"); Object newInstance = class3.newInstance();//或去空参数构造函数对应的对象 //通过Class类中的方法获取带有参数的构造器 Constructor<Person> constructor = class3.getConstructor(String.class,int.class); //通过构造器的方法获取指定对象的对象 Person newInstance2 = constructor.newInstance("xingfeichen",23); System.out.println(newInstance2.getName()); } } //--------------------------------------------------------------------- //上例中的使用到的Person类的内容 package cn.itcait; public class Person { private String name; private int age; public Person() { System.out.println("空参数构造函数"); } public Person(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
1, 使用反射机制如何获取字段
a) 代码演示:
package cn.itcait; import java.lang.reflect.Constructor; import java.lang.reflect.Field; public class Demo02_getFileld { public static void main(String[] args) throws Exception { //获取字节码文件 @SuppressWarnings("unchecked") Class<Person> class1 = (Class<Person>) Class.forName("cn.itcait.Person"); //获取带有参数的构造器,如果需要的第没有参数构造函数,则不需要进行此步骤,直接返回对象即可 Constructor<Person> constructor = class1.getConstructor(String.class,int.class); //传入初始化值。并饭后对象 Person p = constructor.newInstance("chenxinfdhs",12); //获取字段 Field field = class1.getDeclaredField("name"); field.setAccessible(true);//暴力访问私有字段 Object object = field.get(p); System.out.println(object); //System.out.println(p.getName()); } }
1, 反射机制中如何获取方法
a) 有参数方法和无参数方法的调用
package cn.itcait; import java.lang.reflect.Method; @SuppressWarnings({ "unchecked", "unchecked" }) public class Demo03_Method { public static void main(String[] args) throws Exception { //noparamDemo1(); haveparamDemo1(); } private static void haveparamDemo1() throws Exception { @SuppressWarnings("unchecked") //有参数列表的方法的调用 //或去字节码文件 Class<Person> class1 = (Class<Person>) Class.forName("cn.itcait.Person"); //或去对象 Person person = class1.newInstance(); //调用方法返回需要的方法对象 Method method = class1.getMethod("paramMethod", String.class,int.class); //是方法运行 method.invoke(person, "chenjfef",212); } //无参数列表的方法的调用 // private static void noparamDemo1() throws ClassNotFoundException, NoSuchMethodException, InstantiationException, // IllegalAccessException, InvocationTargetException { // Class<Person> class1 = (Class<Person>) Class.forName("cn.itcait.Person"); // Method method = class1.getMethod("method1", null); // Person person = class1.newInstance(); // method.invoke(person, null); // } }1,反射机制综合案例代码:
package com.itcast.myflect_comprehensive; import java.io.File; import java.io.FileInputStream; import java.util.Properties; public class Main_Test { public static void main(String[] args) throws Exception { //创建一个主板对象 MainBoard mb = new MainBoard(); //创建一个文件对象,关联配置文件 File file = new File("my_propertiesFile.ini"); //创建读取流对象,读取文件中的配置文件 FileInputStream fis = new FileInputStream(file); //创建一个Properties集合对象 Properties prop = new Properties(); //将字节流对象中的内容装载到集合中 prop.load(fis); //循环按照指定的规则读取文件。 for (int i = 1; i <= prop.size(); i++) { //通过指定键获取对应的键作为类的字符串路径 String string = prop.getProperty("pci"+i); @SuppressWarnings("unchecked") //通过反射机制获取类的实例 Class<PCI> name = (Class<PCI>) Class.forName(string); PCI pci = name.newInstance(); //通过MainBoard中的run方法进行调用扩展后的内容 mb.run(pci); } //读取结束后,关闭流 fis.close(); } }
package com.itcast.myflect_comprehensive; public class MainBoard { <span style="white-space:pre"> </span>MainBoard(){}; <span style="white-space:pre"> </span>public void run(PCI p){ <span style="white-space:pre"> </span>p.open(); <span style="white-space:pre"> </span>p.close(); <span style="white-space:pre"> </span>} }
package com.itcast.myflect_comprehensive; public class NetBoard implements PCI { <span style="white-space:pre"> </span>@Override <span style="white-space:pre"> </span>public void open() { <span style="white-space:pre"> </span>System.out.println("我的网卡程序运行"); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>@Override <span style="white-space:pre"> </span>public void close() { <span style="white-space:pre"> </span>System.out.println("我的网卡程序运行结束"); <span style="white-space:pre"> </span>} }
package com.itcast.myflect_comprehensive; public interface PCI { <span style="white-space:pre"> </span>public void open(); <span style="white-space:pre"> </span>public void close();<span style="white-space:pre"> </span> }
package com.itcast.myflect_comprehensive; public class SoundBoard implements PCI{ <span style="white-space:pre"> </span>@Override <span style="white-space:pre"> </span>public void open() { <span style="white-space:pre"> </span>System.out.println("我的声卡程序运行"); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>@Override <span style="white-space:pre"> </span>public void close() { <span style="white-space:pre"> </span>System.out.println("我的声卡程序关闭"); <span style="white-space:pre"> </span> <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span> }
版权声明:本文为博主原创文章,未经博主允许不得转载。