《Java核心逻辑第11章反射.ppt》由会员分享,可在线阅读,更多相关《Java核心逻辑第11章反射.ppt(48页珍藏版)》请在三一办公上搜索。
1、第11章 反射,回顾,网络应用的结构 IP地址与端口号 TCP编程 UDP编程,本章目标,class对象 获取class对象的方式 反射包(java.lang.reflect)反射的作用,本章结构,反射,获取class对象,反射包java.lang.reflect,反射的作用,Class.forName()方法,类名.class,Method类,Field类,class对象概念,getClass()方法,Constructor类,思考,给定一个对象,要求输出这个对象所有的public方法的名称public static void printMethod(Object object)给定一个字符
2、串参数,这个参数表示一个类的名字。根据 类名,创建该类的一个对象并返回public static Object createObject(String className),class对象,Customer类是客户的抽象,Customer对象“代表”某个客户,但不是某个客户。抽象一个Customer的过程:,public class Customer private String name;private int age;private String address;/使用字符串表示的地址无法正确的表示地址public Customer(String name,int age,String a
3、ddress)this.name=name;this.age=age;this.address=address;/省略set、get方法,class对象,将address单独封装成一个类Address,public class Address private String province;private String city;private String street;private int code;public Address(String province,String city,String street,int code)this.province=province;this.c
4、ity=city;this.street=street;this.code=code;/省略set、get方法,class对象,将Customer的address属性的类型换成Address类型,public class Customer private String name;private int age;private Address address;/将String类型转换成Address类型public Customer(String name,int age,Address address)this.name=name;this.age=age;this.address=addre
5、ss;/省略set、get方法,class对象,如果想抽象一个Class的信息,那么我们如下来抽象:类中有许多构造函数,有许多方法,有许多成员变量,public class Clazz/构造方法private String construtctors;/字符串无法充分表示的表示构造方法的信息/方法private String methods;/字符串无法充分的表示方法/成员变量private String fields;/字符串无法充分的表示成员变量的信息public Clazz(String construtctors,String methods,String fields)super()
6、;this.construtctors=construtctors;this.methods=methods;this.fields=fields;/省略set、get方法,class对象-1,字符串无法充分的表达各种成员,那么就各成员再次进行抽象,/将Clazz中的各成员对象进行抽象class Constructor class Method class Field,class对象-2,字符串无法充分的表达各种成员,那么就各成员再次进行抽象,public class Clazz private Constructor constructors;/构造方法private Method meth
7、ods;/方法private Field fields;/成员变量public Clazz(Constructor constructors,Method methods,Field fields)this.constructors=constructors;this.methods=methods;this.fields=fields;/省略set、get方法,class对象,Customer类是客户的抽象,Customer对象“代表”某个客户,但不是某个客户。Clazz类是其他类的抽象,Clazz对象代表其他的类。Java已经为我们提供了这样一个类:,我们无需自己定义Clazz类,通过Cl
8、ass对象我们可以得到:类继承自哪个类实现了哪些接口有哪些属性有哪些方法有哪些构造方法.,获取class对象的方式,类名.class,Class clazStudent=Student.class;Class clazInt=int.class;Class clazIntArray=int.class;,获取class对象的方式,getClass()方法,Student student=new Student();Class clazStudent1=student.getClass();Class clazStudent2=Student.class;,获取class对象的方式,Class.
9、forName()方法public static Class forName(String className)throws ClassNotFoundException,Student student=new Student();Class clazStudent1=student.getClass();Class clazStudent2=Student.class;try Class clazStudent3=Class.forName(Student);catch(ClassNotFoundException e)e.printStackTrace();,class对象的作用,getN
10、ame():获得类的名称,包括包名getSimpleName():获得类的名称,不包括包名getSuperClass():获得本类的父类的class对象getInterfaces():获得本类所实现的所有接口的class对象,class对象的作用,Class c=ArrayList.class;String className=c.getName();System.out.println(类名:+className);String simpleName=c.getSimpleName();System.out.println(简单类名:+simpleName);Class superClass
11、=c.getSuperclass();System.out.println(父类:+superClass.getName();Class interfaces=c.getInterfaces();System.out.println(接口:);for(int i=0;i interfaces.length;i+)System.out.println(interfacesi.getName();,class对象的作用,public Method getDeclaredMethods()throws SecurityException取得所有当前类声明的方法,包括public,protected,
12、默认,private四种访问权限的方法,但是不包括继承的方法public Method getMethods()throws SecurityException取得所有public的方法,包括继承的,接口中声明的和自己定义的,class对象的作用,public class Student public String name;private int age;static final String KIND=human;protected String schoolName;public Student()public Student(String name,int age)this.name=
13、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;public void publicStudy(int h)System.out.println(调用publicStudy学习时间是:+h);protected void protectedStudy(int h)System.out.println(调用p
14、rotectedStudy学习时间是:+h);void friendlyStudy(int h)System.out.println(调用friendlyStudy学习时间是:+h);private void privateStudy(int h)System.out.println(调用privateStudy学习时间是:+h);,class对象的作用,获得所有的公开方法,Class clazStudent=Student.class;Method publicMethods=clazStudent.getMethods();System.out.println(=所有public方法=);
15、for(Method method:publicMethods)System.out.println(method.getName();,class对象的作用,获得所有的本类中定义的方法,Class c=Student.class;Method declaredMethods=c.getDeclaredMethods();System.out.println(=所有当前的类自己定义的方法=);for(Method m:declaredMethods)System.out.println(m.getName();,class对象的作用,Field getDeclaredFields()取得所有当
16、前类自己定义的属性,包括四种访问权限的 Field getFields()取得所有public的属性,包括继承的,接口中声明的和自己定义的,class对象的作用,获得所有的公开属性,Class c=Student.class;Field publicMethods=c.getFields();System.out.println(=所有public属性=);for(Field field:publicMethods)System.out.println(field.getName();,public class Student public String name;private int ag
17、e;/其他代码,class对象的作用,获得本类中定义的属性,Class clazStudent=Student.class;Field declaredFields=clazStudent.getDeclaredFields();System.out.println(=获取当前类自己定义的属性=);for(Field field:declaredFields)System.out.println(field.getName();,public class Student public String name;private int age;static final String KIND=hu
18、man;protected String schoolName;/省略其他代码,使用class对象创建类的对象,Object newInstance(),Class clazStudent=Student.class;Student student;try student=clazStudent.newInstance();student.setName(zhangsan);System.out.println(student.getName();catch(InstantiationException e)e.printStackTrace();catch(IllegalAccessExce
19、ption e)e.printStackTrace();,反射包,类通过Class对象的如下方法可以获得Field对象Field getDeclaredField(String name)Field getField(String name)Field getDeclaredFields()Field getFields(),Field类的常见方法,getName(),Class c=Student.class;Field nameField;try nameField=c.getDeclaredField(name);System.out.println(nameField.getName(
20、);catch(NoSuchFieldException e)e.printStackTrace();catch(SecurityException e)e.printStackTrace();,Field类的常见方法,读取、设置属性public void set(Object obj,Object value)public Object get(Object obj)Student stu=new Student();stu.name=tom;/修改属性值,Field类的常见方法,Student student=new Student();Class clazStudent=student.
21、getClass();Field nameField;try nameField=clazStudent.getField(name);nameField.set(student,张三);/使用field对象读取属性System.out.println(nameField.get(student);/使用student对象方法读取属性System.out.println(student.getName();catch(NoSuchFieldException e)e.printStackTrace();catch(SecurityException e)e.printStackTrace();
22、catch(IllegalArgumentException e)e.printStackTrace();catch(IllegalAccessException e)e.printStackTrace();,Field类的常见方法,访问类自己定义的私有属性public void setAccessible(boolean flag)Student stu=new Student();/stu.age=20;不能直接修改age属性,这句代码将无法编译通过,Field类的常见方法,Student student=new Student();Class clazStudent=student.ge
23、tClass();Field ageField;try ageField=clazStudent.getDeclaredField(age);/可以操作私有属性,至关重要ageField.setAccessible(true);ageField.set(student,20);/使用field对象读取属性System.out.println(ageField.get(student);/使用student对象的方法读取属性System.out.println(student.getAge();catch(NoSuchFieldException e)e.printStackTrace();ca
24、tch(SecurityException e)e.printStackTrace();catch(IllegalArgumentException e)e.printStackTrace();catch(IllegalAccessException e)e.printStackTrace();,反射包,类通过Class对象的如下方法可以获得Method对象public Method getDeclaredMethods()public Method getMethods()public Method getMethod(String name,Class parameterTypes)pub
25、lic Method getDeclaredMethod(String name,Class parameterTypes)红色位置为变长参数。,Method类的常见方法,Student类public void privateStudy(int h)Method m=c.getDeclaredMethod(“privateStudy”,int.class),Method类的常见方法,通过反射调用方法Method.invoke(Object,Object);,Student student=new Student();Class clazStudent=student.getClass();tr
26、y Method privateStudyMethod=clazStudent.getDeclaredMethod(privateStudy,int.class);/调用的方法是public的,就不需要进行设置privateStudyMethod.setAccessible(true);privateStudyMethod.invoke(student,24);catch(NoSuchMethodException e)e.printStackTrace();catch(SecurityException e)e.printStackTrace();catch(IllegalAccessExc
27、eption e)e.printStackTrace();catch(IllegalArgumentException e)e.printStackTrace();catch(InvocationTargetException e)e.printStackTrace();,反射包,java.lang.reflect.Constructor 类通过Class对象的如下方法可以获得Constructor对象 Constructor getConstructors()取得public的构造函数 Constructor getDeclaredConstructors()取得所有的构造函数 Constr
28、uctor getConstructor(Class parameters)Constructor getDeclaredConstructor(Class parameters),反射包,try Class clazStudent=Class.forName(chp16.ex08.Student);Constructor constructor=clazStudent.getConstructor(String.class,int.class);Student student=(Student)constructor.newInstance(张三,24);System.out.println
29、(该学生的年龄是+student.getAge();catch(NoSuchMethodException e)e.printStackTrace();catch(SecurityException e)e.printStackTrace();catch(IllegalAccessException e)e.printStackTrace();catch(IllegalArgumentException e)e.printStackTrace();catch(InvocationTargetException e)e.printStackTrace();catch(ClassNotFoundE
30、xception e)e.printStackTrace();catch(InstantiationException e)e.printStackTrace();,反射的作用,应用反射的代码,增加程序的通用性Student s=new Student();s.study();String className=Student;Class c=Class.forName(className);Object o=c.newInstance();String methodName=“publicStudy;Method m=c.getMethod(methodName,int.class);m.in
31、voke(o,12);,反射案例-1,Animal类,public abstract class Animal private String name;public Animal(String name)this.name=name;/*动物叫*/public abstract void shout();/*动物吃*/public abstract void eat();public String getName()return name;public void setName(String name)this.name=name;,反射案例-2,Bird类,public class Bird
32、 extends Animal public Bird(String name)super(name);Overridepublic void shout()System.out.println(+this.getName()+小鸟,在唧唧喳喳叫.);Overridepublic void eat()System.out.println(+this.getName()+小鸟,早吃虫子.);,反射案例-3,Cat类,public class Cat extends Animal public Cat(String name)super(name);Overridepublic void shou
33、t()System.out.println(+this.getName()+小猫,在喵喵叫.);Overridepublic void eat()System.out.println(+this.getName()+小猫,在吃鱼.);,反射案例-4,Dog类,public class Dog extends Animal public Dog(String name)super(name);Overridepublic void shout()System.out.println(+this.getName()+小狗,在汪汪叫.);Overridepublic void eat()System
34、.out.println(+this.getName()+小狗,在吃骨头.);,反射案例-4,创建一个名为reflect.properties的文件,内容如下:,argValue=u65FAu8D22,反射案例-5,AnimalFactory类,public class AnimalFactory/类名public static final String CLAZZ_NAME;/参数值public static final String ARG_VALUE;/加载类名static InputStream is=AnimalFactory.class.getClass().getResource
35、AsStream(/reflect.properties);Properties properties=new Properties();try properties.load(is);catch(IOException e)e.printStackTrace();CLAZZ_NAME=properties.getProperty(clazzName);ARG_VALUE=properties.getProperty(argValue);/省略其他代码,反射案例-6,AnimalFactory类,public class AnimalFactory/省略代码public static Anim
36、al getAnimalInstance()Animal animal=null;try Class clazz=Class.forName(CLAZZ_NAME);Constructor constructor=clazz.getConstructor(new Class String.class);animal=(Animal)constructor.newInstance(new Object ARG_VALUE);catch(Exception e1)e1.printStackTrace();return animal;,反射案例-7,Test 测试类,public class Test public static void main(String args)Animal animal=AnimalFactory.getAnimalInstance();animal.shout();animal.eat();,反射案例-8,获取动物对象,概述,在本章讨论了:class对象 获取class对象的方式 反射包(java.lang.reflect)反射的作用,