反射类入门学习

来源:互联网 发布:安卓手机安装windows 编辑:程序博客网 时间:2024/06/07 03:08

以person为例子

package com.itcast.reflection;

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 static void main(String args[]){
        System.out.println("main");
    }
    /*
     * 构造函数部分
     */
    public Person(){
        System.out.println("person");
    }
    
    public Person(String name){
        System.out.println(name);
    }
    
    public Person(String name,int password){
        System.out.println(name+"\r"+password);
    }
    
    private Person(List list){
        System.out.println("list");
    }
    
    /*
     *方法部分:
     */
    public void method1(){
        System.out.println("Method1");
    }
    
    public void method2(String name,int password){
        System.out.println(name+" "+password);
    }
    
    public Class[] method3(String name,int[] password){
        return new Class[]{String.class};
    }
    
    private void method4(InputStream in){
        System.out.println(in);
    }
    
    public static void method5(int num){
        System.out.println(num);
    }
}

反射构造函数

package com.itcast.reflection;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class TestConstructor {
    
    
    //**为什么get Qualified name 返回格式不对
    //答:下载插件 使用ctrl+alt+c 可以复制完整类名
    @Test
    //反射构造函数 public Person()
    public void test1() throws Exception {
        Class clazz = Class.forName("com.itcast.reflection.Person");
        //Class clazz1 = new Person().getClass();
        //Class clazz2 = Person.class;
        Constructor c = clazz.getConstructor(null);
        Person p = (Person) c.newInstance(null);
        
    //反射是用于做框架的 所以 Person p = new Person(null); System.out.println(p.name);并不能用 所以才有上面的方法
        
    //**框架要用到反射类 主要原理是什么?
    //答:一般可以用在后台和前台的联系,可以让你仅知道类的名字的情况下,可以了解整个类的内部的结构,并且访问内部的成员和方法等。
    }
    
    //反射构造函数  public Person(String name)
    @Test
    public void test2() throws Exception{
        Class clazz = Class.forName("com.itcast.reflection.Person");
        Constructor c = clazz.getConstructor(String.class);
        Person p =(Person) c.newInstance("xxx");
        System.out.println(p.name);
    }
    
    
    //反射构造函数  public Person(String name,int password)
    @Test
    public void test3() throws Exception{
        Class clazz = Class.forName("com.itcast.reflection.Person");
        Constructor c = clazz.getConstructor(String.class,int.class);
        Person p = (Person) c.newInstance("xxx",123);
        System.out.println(p.name);
        
    }
    
    
    /*private Person(List list)
    *补充:面试题 :
    *问:私有的东西外部可以访问吗?
    *答:私有的东西只能被类内部访问,但是反射类可以做到
    */
    @Test
    public void test4() throws Exception{
        Class clazz = Class.forName("com.itcast.reflection.Person");
        Constructor c = clazz.getDeclaredConstructor(List.class);
        c.setAccessible(true);
        //暴力反射,强行打开
        Person p = (Person) c.newInstance(new ArrayList());
        System.out.println(p.name);
    }
    
    @Test
    //上述代码等价于test1()方法,但是这样只能创建类的无参构造函数
    public void test5() throws Exception{
        Class clazz = Class.forName("com.itcast.reflection.Person");
        Person p = (Person) clazz.newInstance();
        System.out.println(p.name);
    }
    
    
}


反射类里面的方法

package com.itcast.reflection;

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

import org.junit.Test;

public class TestMethod {
    
    //getMethod方法里面的两个参数第一个是方法名,后面的若干个参数是入参类型
    //Method对象的invoke的参数,前面的是对象名,而后面的参数是入参
    //测试类的空方法  public void method1()
    @Test
    public void test1() throws Exception{
        Person p = new Person();
        Class clazz = Class.forName("com.itcast.reflection.Person");
        Method m = clazz.getMethod("method1", null);
        m.invoke(p, null);
    }
    
    //测试方法 public void method2(String name,int password)
    @Test
    public void test2()throws Exception{
        Person p = new Person();
        Class clazz = Class.forName("com.itcast.reflection.Person");
        Method m = clazz.getMethod("method2",String.class,int.class );
        m.invoke(p, "user1",123);
    }
    
    //测试方法 public Class[] method3(String name,int[] password)
    @Test
    public void test3()throws Exception{
        Person p = new Person();
        Class clazz = Class.forName("com.itcast.reflection.Person");
        Method m = clazz.getMethod("method3",String.class,int[].class);
        Class cs[] =(Class[]) m.invoke(p, "user",new int[]{1,2,3});
        System.out.println(cs[0]);
        
    }
    
    //测试方法 private void method4(InputStream in)
    @Test
    public void test4() throws Exception{
        Person p = new Person();
        Class clazz = Class.forName("com.itcast.reflection.Person");
        Method m = clazz.getDeclaredMethod("method4", InputStream.class);
        m.setAccessible(true);
        m.invoke(p, new FileInputStream("1.txt"));
        
    }
    
    //测试方法public static void method5(int num)
    @Test
    public void test5() throws Exception{
        Class clazz = Class.forName("com.itcast.reflection.Person");
        Method m = clazz.getMethod("method5", int.class);
        m.invoke(null, 1);
        m.invoke(Person.class, 2);
    }
    
    //调用反射类的静态方法
    //测试方法public static void main(String args[])
    @Test
    public void test6() throws Exception{
        Class clazz = Class.forName("com.itcast.reflection.Person");
        Method m = clazz.getMethod("main", String[].class);
        //error 错误代码 错误的参数个数 解决方法如下
        //m.invoke(null, new String[]{"11","22"});
        
        //注意:用反射在在调用一个接受数组的方法时,要小心,会被拆开,可以用下面的两种解决方案来处理
        //解决方案1
        //再在所需入参外面加多一个数组,拆完刚好为所得
        m.invoke(null, new Object[]{new String[]{"11","22"}});
        //解决方案2
        //将其强转为(object),欺骗其为object对象
        m.invoke(null, (Object)new String[]{"11","22"});
        
    }
    
    //jdk1.5 Method.invoke(Object obj,Object...args);
    //jdk1.4 Method.invoke(Object obj,Object[]);
    //jdk1.4 Method.invoke(Object obj,new Object[]{"aaa","123"});
    //1.5向下兼容 故在使用这个方法的时候,会沿用1.4拆分String数组,故方法变为Method.invoke(Object obj,String s1,String s2);
    //因此才会出现错误参数个数的问题,具体有2个解决方法:
    
    
}

反射类的自变量

package com.itcast.reflection;

public class TestReflection {
    public static void main(String argsp[]) throws ClassNotFoundException {

        // 3种加载类字节码的方法

        // 1
        Class clazz = Class
                .forName("/Java150415/src/com/itcast/reflection/Person");
        // 2
        Class clazz1 = new Person().getClass();
        // 3
        Class clazz2 = Person.class;
        /*
         *反射 第一步要先加载类
         *使用加载类的目的是在于从类中解剖出构造函数 方法 变量来提供使用 解剖出来的成员分别用Constructor Method Field对象表示
         *public Constructor getConstructor()
         *public Method getMethod()
         *public Field getField()    
         *这三种方法只使用于该类中的方法为public的情况,
         *而对于访问解剖类的private方法,则应该使用下面的方法
         *
         *
         *public Constructor getDeclaredConstructor()
         *public Method getDeclaredMethod()
         *public Field getDeclaredField()
         *
         */
        
        
    }
}


主要应用在框架


0 0
原创粉丝点击