Oracle培训(十六)——Core Java第十六章知识点小结——反射
Core Java第十六章知识点总结——反射
知识点预览
类对象
获取类对象的方式
反射包java.net.reflect
反射的作用
思考
1. 给定一个对象,要求输出这个对象的所有方法
public static void printMethod(Objectobject);
2.给顶一个字符串参数,这个参数表示一个类的名字,根据类名,创建该类的一个对象并返回
public static Object createObject(StringclassName);
类对象
1.java.lang.Class类的对象
类继承自哪个类
实现了哪些接口
有哪些属性
有哪些方法
有哪些构造方法
……
2.保存类的信息
.class读到JVM后用一个类存储
例:动物园里的熊猫笼子 笼子外面的熊猫标识牌(可以看成类对象)
获取类对象的方式(三种)
1. 类名.class
Class c = Student.class;
Class i = int.class();//8种基本数据类型也有类对象
2. getClass()方法(Object类定义)
以前讲的获取对象的实际类型(不准确),应该是获得某个类的类对象
Student s = new Student();
Class cs1 = s.getClass();
Class cs2 = Student.class;
不管是类的什么对象,不管以什么方式,获得的都是同一个类对象
3.Class.forName()方法
public static Class forName(String className) throws ClassNotFoundException
Class c = Class.forName(“ex04.Student”);//全限定名
Class.forName():类加载方法
4. 本章中使用的Student类的定义:
package chp16.ex01; /** * * @Author: Wentasy * @FullName: Student.java * @Description: Student类的定义 * @Create Date: 2012-8-20 */ public class Student { public String name; private int age; public Student(){} 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 study(){ System.out.println(name + " study"); } public void study(int h){ System.out.println(name + " study for " + h + " hours"); } public double study(int a, double b){ System.out.println(name + " study " + a + " " + b); return a * b; } private void play(){ System.out.println(name + " play"); } }
类对象的作用
1. 类对象的作用——获得类信息
2. 常用方法
a) getName():获得类的名称,包括包名
b)getSimpleName():获得类的名称,不包括包名
c) getSuperClass():获得本类的父类的类对象
d) getInterfaces():获得本类所实现的所有接口的类对象
3. 方法
a) public Method[] getDeclaredMethods()throws SecurityException
b) public Method[] getMethods()throws SecurityException
c) Method(java.lang.reflect.Method)
d) 获得对象的方法
i.获得所有的公开方法(包括本类和继承)
Class c = Student.class; Method[] ms = c.getMethods();//获得所有 for(Method m : ms){ System.out.println(m); }
ii.获得所有的本类中定义的方法(公开、私有方法都能获得)
Class c = Student.class; Method[] ms = c.getDeclaredMethods(); for(Method m : ms){ System.out.println(m); }
4. 属性
a) Field[] getDeclaredFields();
b)Field[] getFields();
c) Field:属性,也称字段,属性信息包括修饰符、类型、属性名
d)获得对象的属性
i.获得所有的公开属性(包括父类)
Class c = Student.class; Field[] fs = c.getFields (); for(Field f : fs){ System.out.println(f); }
ii. 获得本类中定义的属性
Class c = Student.class; Field[] fs = c. getDeclaredFields (); for(Field f : fs){ System.out.println(f); }
5.使用类对象创建类的对象
Object new Instance(); Class c = Student.class; Student s = (Student)c.newInstance(); //调用了无参构造方法----->创建类对象
反射包
1.java.lang.reflect.Field类
通过Class对象的如下方法可以获得Field对象
FieldgetDeclaredField(String name);//name:属性名
FieldgetField(String name)
Field[]getDeclaredField();
Field[]getField()
Class:java.lang.Class
a) Field类的常用方法
i. getName();//获得属性
Class c = Student.class; Field f = c.getDeclaredField("name"); System.out.println(f.getName());
ii. 属性赋值、获取
public void set(Objectobj,Object value);
public Objectget(Object obj);
Student stu = new Student(); stu.name = “tom”;//修改属性值 Student stu = new Student(); Class cs = stu.getClass(); Field f = cs.getField("name"); f.set(stu, "tom"); Student stu = new Student(); String date = stu.name;//获取属性值 Student stu = new Student(); Class cs = stu.getClass(); Field f = cs.getField("name"); String data = (String)f.get(stu);
iii. public void Accessible(booleanflag)
直接操作私有属性,打破封装
Student stu = new Student(); //stu.age = 18;//不能直接修改age属性,这句代码将无法编译通过 Student stu = new Student(); Class cs = stu.getClass(); Field f = cs.getDeclaredField("age"); f.setAccessible(true);//可以操作私有属性 f.set(stu, 10);
2.java.lang.reflect.Method类
通过Class对象的如下方法可以获得Method对象
public Method[] getDeclaredMethods();
public Method[] getMethods();
public Method getMethod(String name,Class[] parameterTypes);
public Method getDeclaredMethod(String name,Class[] parameterTypes);
a) Student类
b) 通过调用Method.invoke(Object,Object[])执行方法;
Student stu1 = new Student(); stu1.study(10, 10.2); Student stu2 = new Student(); Class sc = stu2.getClass(); Method m = sc.getDeclaredMethod("study", new Class[]{int.class,double.class}); m.invoke(stu2, new Object[]{10,10.2});
3.java.lang.reflect.Constructor类
通过Class对象的如下方法可以获得Constructor对象
Constructor[]getConstructors();
Constructor[]getDeclaredConstructors();//可以获得私有的构造方法
Constructor getConstructor(Class[]parameters);
ConstructorgetDeclaredConstructor(Class[] parameters);
Student stu = new Student(); Class cs = stu.getClass(); Constructor c = cs.getDeclaredConstructor(new Class[]{String.class,int.class}); c.newInstance(new Object[]{"suns",10});
反射的作用
1.应用反射的代码,增加程序的通用性
2.反射+文件----------->代码不会变改变文件文件,文本文件不需要重新编译
3.反射:不建议使用,程序效率降低
package chp16.ex10; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Method; /** * * @Author: Wentasy * @FullName: TestStudent.java * @Description: 反射的好处:应用反射的代码,增加程序的通用性 * @Create Date: 2012-8-20 */ public class TestStudent { public static void main(String args[])throws Exception{ InputStream is = new FileInputStream("refelection.txt"); InputStreamReader ir = new InputStreamReader(is); BufferedReader br = new BufferedReader(ir); String className = br.readLine(); String methodName = br.readLine(); Class c = Class.forName(className); Object o = c.newInstance(); Method m = c.getDeclaredMethod(methodName); m.setAccessible(true); m.invoke(o); } } //refelection.txt内容: //ex20.Student //play