zoukankan      html  css  js  c++  java
  • 反射

    反射技术主要是用来做框架

    一个类有多个组成部分,例如:成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分。

    编程时什么情况下才需要加载类,并解剖出类的各个组成部分呢?

    1、加载类
    Java中有一个Class类用于代表某一个类的字节码。

    Class类即然代表有个类的字节码,它当然就要提供加载某个类字节码的方法:forName()。forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装

    另外两种得到class对象的方式
    类名.class
    对象.getClass()

    2、解剖类
    Class对象提供了如下常用方法:
    Public Constructor getConstructor(Class<?>...parameterTypes) //获得公共构造函数
    Public Method getMethod(String name,Class<?>...parameterTypes) //获得公共方法
    Public Field getField(String name) //获得公共属性

    public Constructor getDeclaredConstructor(Class<?>...parameterTypes) //获得所有构造函数
    public Method getDeclaredMethod(String name,Class<?>...parameterTypes) //获得所有方法
    public Field getDeclaredField(String name) //获得所有属性

    这些方法分别用于从类中解剖出构造函数、方法和成员变量(属性)。解剖出的成员分别使用Constructor、Method、Field对象表示。

    3、利用Constructor创建对象
    Constructor类提供了如下方法,用于创建类的对象:
    public Object newInstance(Object... initargs)
    initargs用于指定构造函数接收的参数

    多学一招:sun公司为简化开发人员创建对象,它class对象中也提供了一个newInstance方法,用于创建类的对象。这样开发人员可以避免每次都需要去反射Constructor类以创建对象。

    不过需要注意的是:class.newInstance方法内部是反射类无参的构造函数创建的对象,所以利用此种方式创建类对象时,类必须有一个无参的构造函数。

    4、利用Method执行方法
    Method对象提供了如下方法,用于执行它所代表的方法:
    public Object invoke(Object obj,Object... args)
    jdk1.4和jdk1.5的invoke方法的区别
    jdk1.5:public Object invoke(Object obj,Object... args)
    jdk1.4:public Object invoke(Object obj,Object[] args)

    5、

    代码1(Person类):

    package cn.itcast.reflect;

    import java.io.InputStream;
    import java.util.List;

    public class Person {
    public String name = "aaa";
    private int password=123;
    private static int age=23;

    public Person() {
    System.out.println("person");
    }

    public Person(String name) {
    System.out.println(name);
    }

    public Person(String name, int password) {
    System.out.println(name + ":" + password);
    }

    private Person(List list) {
    System.out.println("list");
    }

    public void aa1() {
    System.out.println("aa1");
    }

    public void aa1(String name, int password) {
    System.out.println(name + ":" + password);
    }

    public Class[] aa1(String name, int[] password) {
    return new Class[] { String.class };
    }

    private void aa1(InputStream in) {
    System.out.println(in);
    }

    public static void aa1(int num) {
    System.out.println(num);
    }

    public static void main(String[] args) {
    System.out.println("main!!");
    }
    }

    代码2(Demo1类):

    package cn.itcast.reflect;

    public class Demo1 {

    /**
    * 反射:加载类
    *
    * @param args
    * @throws ClassNotFoundException
    */
    public static void main(String[] args) throws ClassNotFoundException {

    // 1.
    Class clazz = Class.forName("cn.itcast.reflect.Person");

    // 2.
    Class clazz1 = new Person().getClass();

    // 3.
    Class clazz2 = Person.class;

    }

    }

    代码3(Demo2类):

    package cn.itcast.reflect;

    import java.lang.reflect.Constructor;

    import java.util.ArrayList;
    import java.util.List;

    import org.junit.Test;

    //解剖类的构造函数,创建类的对象
    public class Demo2 {

    // 反射构造函数:public Person()
    @Test
    public void test1() throws Exception {
    Class clazz = Class.forName("cn.itcast.reflect.Person");
    Constructor c = clazz.getConstructor(null);
    Person p = (Person) c.newInstance(null);
    System.out.println(p.name);
    }

    // 反射构造函数:public Person(String name)
    @Test
    public void test2() throws Exception {
    Class clazz = Class.forName("cn.itcast.reflect.Person");
    Constructor c = clazz.getConstructor(String.class);
    Person p = (Person) c.newInstance("xxxxxx");
    System.out.println(p.name);
    }

    // 反射构造函数:public Person(String name,int password)
    @Test
    public void test3() throws Exception {
    Class clazz = Class.forName("cn.itcast.reflect.Person");
    Constructor c = clazz.getConstructor(String.class, int.class);
    Person p = (Person) c.newInstance("yyy", 112);
    System.out.println(p.name);
    }

    // 反射构造函数:public Person(List list)
    @Test
    public void test4() throws Exception {
    Class clazz = Class.forName("cn.itcast.reflect.Person");
    Constructor c = clazz.getDeclaredConstructor(List.class);
    c.setAccessible(true);// 暴力反射
    Person p = (Person) c.newInstance(new ArrayList());
    System.out.println(p.name);
    }

    // 创建对象的另外一种途径:以下代码,等效于test1
    @Test
    public void test5() throws Exception {
    Class clazz = Class.forName("cn.itcast.reflect.Person");
    Person p = (Person) clazz.newInstance();
    System.out.println(p.name);
    }
    }

    代码4(Demo3类):

    package cn.itcast.reflect;

    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.lang.reflect.Method;

    import org.junit.Test;

    //反射类的方法
    public class Demo3 {

    // 反射类的方法:public void aa1()
    @Test
    public void test1() throws Exception {
    Person p = new Person();
    Class clazz = Class.forName("cn.itcast.reflect.Person");
    Method method = clazz.getMethod("aa1", null);
    method.invoke(p, null);
    }

    // 反射类的方法:public void aa1(String name,int password)
    @Test
    public void test2() throws Exception {
    Person p = new Person();
    Class clazz = Class.forName("cn.itcast.reflect.Person");
    Method method = clazz.getMethod("aa1", String.class, int.class);
    method.invoke(p, "zxx", 38);
    }

    // 反射类的方法:public void aa1(String name,int password)
    @Test
    public void test3() throws Exception {
    Person p = new Person();
    Class clazz = Class.forName("cn.itcast.reflect.Person");
    Method method = clazz.getMethod("aa1", String.class, int[].class);
    Class cs[] = (Class[]) method.invoke(p, "zxx", new int[] { 1, 2, 3 });
    System.out.println(cs[0]);
    }

    // 反射类的方法:private void aa1(InputStream in)
    @Test
    public void test4() throws Exception {
    Person p = new Person();
    Class clazz = Class.forName("cn.itcast.reflect.Person");
    Method method = clazz.getDeclaredMethod("aa1", InputStream.class);
    method.setAccessible(true);
    method.invoke(p,new FileInputStream("c:\1.txt"));
    }

    // 反射类的方法:public static void aa1(int num)
    @Test
    public void test5() throws Exception {
    Class clazz = Class.forName("cn.itcast.reflect.Person");
    Method method = clazz.getMethod("aa1", int.class);
    method.invoke(null,11);
    }

    // 反射类的方法:public static void main(String[] args)
    @Test
    public void test6() throws Exception {
    Class clazz = Class.forName("cn.itcast.reflect.Person");
    Method method = clazz.getMethod("main", String[].class);
    method.invoke(null,new Object[]{new String[]{"aa","bb"}});

    method.invoke(null,(Object)new String[]{"aa","bb"});

    //jdk1.5 Method.invoke(String methodName,Object... args); 为了兼容之前的版本,遇到数组会拆
    //jdk1.4 Method.invoke(String methodName,Object args[]);
    }
    }

    代码5(Demo4类):

    package cn.itcast.reflect;

    import java.lang.reflect.Field;

    import org.junit.Test;

    //反射字段
    public class Demo4 {

    // 反射字段:public String name = "aaa";
    @Test
    public void test1() throws Exception {
    Person p=new Person();
    Class clazz = Class.forName("cn.itcast.reflect.Person");
    Field f=clazz.getField("name");
    //获取字段的值
    Object obj=f.get(p);
    //获取字段的类型
    Class type=f.getType();
    if(type.equals(String.class)){
    String value=(String)obj;
    System.out.println(value);
    }

    //设置字段的值
    f.set(p, "xxxx");
    System.out.println(p.name);
    }

    // 反射字段:private int password;
    @Test
    public void test2() throws Exception {
    Person p=new Person();
    Class clazz = Class.forName("cn.itcast.reflect.Person");
    Field f=clazz.getDeclaredField("password");
    f.setAccessible(true);
    System.out.println(f.get(p));
    }

    // 反射字段:private static int age;
    @Test
    public void test3() throws Exception {
    Person p=new Person();
    Class clazz = Class.forName("cn.itcast.reflect.Person");
    Field f=clazz.getDeclaredField("age");
    f.setAccessible(true);
    System.out.println(f.get(p));
    }
    }

  • 相关阅读:
    hiho一下 第115周:网络流一•Ford-Fulkerson算法 (Edmond-Karp,Dinic,SAP)
    hiho一下 第二周&第四周:从Trie树到Trie图
    2016 acm香港网络赛 C题. Classrooms(贪心)
    2016 acm香港网络赛 F题. Crazy Driver(水题)
    2016 acm香港网络赛 B题. Boxes
    系统吞吐量(TPS)、用户并发量、性能测试概念和公式(转发)
    使Eclipse下支持编写HTML/JS/CSS/JSP页面的自动提示。
    Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析
    Tomcat 系统架构与设计模式,第 1 部分: 工作原理
    Tomcat源码分析
  • 原文地址:https://www.cnblogs.com/xiaohuihui123/p/4359046.html
Copyright © 2011-2022 走看看