2020-11-07 反射基础

反射

new只能用于编译期就能确定的类型, 而反射可以在运行时才确定类型并创建其对象.

获取class对象的机制

Filed[] files

Constructor[] constructor

Method[] method

相对应的get和getDeclared方法来获得成员方法、构造放方法、和普通方法

class.forname("")

类名.class 多用于参数的传递

多用于对象获得字节码文件

三种方式

new 三个对象肯定是false,内存空间是不一样

通过反射生成的对象,内存空间是一样的。实际上只有一个Class。

public class refulectDemo1 {
    /**
     *  1.Class.forName("全类名"):将字节码文件加载进内存,返回class对象
        2.类名.class:通过类名的class获取
        3.对象.getClass(): getClass()方法在object类当中定义着
     * @throws ClassNotFoundException 
     */
    public static void main(String[] args) throws Exception {
        // 1.Class.forName("全类名"):
        Class class1 = Class.forName("reflect.Person");
        System.out.println(class1);
        //2.类名.class:通过类名的class获取
        Class class2 = Person.class;
        System.out.println(class2);
        //3.对象.getClass()
        Person person = new Person();
        Class class3 = person.getClass();
        System.out.println(class3);
    
    }
}

结论:

同一类加载器加载的文件(*.class)在一次程序运行过程中,只会被加载一次,不论你通过那种方式获取的class对象都是同一个。

  • Filed Filed[]

  • get Filed是获取指定的名称

  • public可以用get Filed直接获取

  • 而getDeclaredFiled();

  • Constructor Constructor[]

  • Methode Method[]

*class对象功能

*class对象功能
*获取功能
·           1.获取成员变量们
1.Field[] getFields() :获取所有public修饰的成员变量 
2.Field getField(String name):获取指定名称的
3.Field[] getDeclaredFilds():获取所有的成员变量,不考虑修饰符
4.Field getDeclaredField(String name)
   2.获取构造方法们
1.Constructor<?>[] getConstructors()
2.Constructor<T> getConstructor(类<?>...parameterTypes)
3.Constructor<?>[] getDeclaredConstructors()
4.Constructor<T> getDeclaredConstructors(类<?>...parameterTypes)
   3.获取方法名
1.Method[] getMethod()
2.Method getMethod(String name,类<?>... parameterTypes)
3.Method[] getDeclaredMethod()
4.Method getDeclaredMethod(String name,类<?>... parameterTypes)
    4.获取类名
String getName()
​

Field

 

public static void main(String[] args) throws Exception {
​
        //0.获取Person的Class对象
        Class personClass = Person.class;
        /*
             1. 获取成员变量们
                 * Field[] getFields()
                 * Field getField(String name)
​
                 * Field[] getDeclaredFields()
                 * Field getDeclaredField(String name)
​
         */
        //1.Field[] getFields()获取所有public修饰的成员变量
        Field[] fields = personClass.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
​
        System.out.println("------------");
        //2.Field getField(String name)
        Field a = personClass.getField("a");
        //获取成员变量a 的值
        Person p = new Person();
        Object value = a.get(p);
        System.out.println(value);
        //设置a的值
        a.set(p,"张三");
        System.out.println(p);
​
        System.out.println("===================");
​
        //Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        //Field getDeclaredField(String name)
        Field d = personClass.getDeclaredField("d");
        //忽略访问权限修饰符的安全检查
        d.setAccessible(true);//暴力反射
        Object value2 = d.get(p);
        System.out.println(value2);
​
    }
​

Constructor

*创建对象

*T newInstance(Object... initarges)

*如果使用空参数构造方法,此操作可以简化:class对象的newInstance方法

public static void main(String[] args) throws Exception {
        //0.获取Person的class对象
        Class personClass = Person.class;
​
        //因为构造器的方法名称是相同的,不同的是参数列表,所以我们可以根据不同的参数列表来找到构造器
        Constructor constructor = personClass.getConstructor(String.class,int.class);
        System.out.println(constructor);
        //创建对象
        Object perObject = constructor.newInstance("张三",20);
        System.out.println(perObject);
        
        System.out.println("-------------------------------");
    
        Constructor constructor1 = personClass.getConstructor();
        System.out.println(constructor1);
        //创建对象
        Object perObject1 = constructor1.newInstance();
        System.out.println(perObject1);
        
        System.out.println("-------------------------------");
        Object o = personClass.newInstance();
        System.out.println(o);
    }

Method

*执行方法

*object invoke(Object object,Object... ages)

*获取方法名称

*String getName:获取方法名

public static void main(String[] args) throws Exception {
        //0.获取Person的class对象
        Class personClass = Person.class;
        
        //获取指定名称的方法,方法无参
        Method eat_method = personClass.getMethod("eat");
        //执行方法
        Person person =new Person();
        eat_method.invoke(person);
        
        //获取指定名称的方法,方法有参
        Method eat_method1 = personClass.getMethod("eat",String.class);
        //执行方法
        eat_method1.invoke(person,"饭");
        
        //获取所有public修饰的方法
        Method[] methods = personClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
            //获取方法的名称
            String name = method.getName();
            System.out.println(name);
        }
    }

 

暴力反射

构造方法和暴力反射

  public static void main(String[] args) {
        try {
            Class class1 = Class.forName("com.Reflection.Driver");
​
            Field afield = class1.getField("str");
            Driver driver0 = new Driver();
            Object obj = afield.get(driver0);
            System.out.println(afield);
            System.out.println(obj);
​
            Driver driver = new Driver();
            Field namefield = class1.getDeclaredField("name");
            namefield.setAccessible(true);
            namefield.set(driver,1);
            Object strobj = namefield.get(driver);
            System.out.println(driver.toString());
            Constructor[] constructors = class1.getConstructors();
            System.out.println(Arrays.toString(constructors));
            Constructor[] constructors1=class1.getDeclaredConstructors();
            System.out.println(Arrays.toString(constructors1));
            Constructor constructor = class1.getConstructor(String.class);
            System.out.println(constructor);
            Constructor constructor1 = class1.getDeclaredConstructor(int.class,int.class);
            constructor1.setAccessible(true);
            Object object = constructor1.newInstance(2,12);
            System.out.println(object);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

 

 

 

普通方法

普通方法和暴力反射

   public static void main(String[] args) {
        try {
            Class class1 = Class.forName("com.Reflection.Driver");
            Method[] methods = class1.getMethods();
            Method methods1 = class1.getDeclaredMethod("run",null);
            methods1.setAccessible(true);
            //Object obj = methods1.getName();
            //System.out.println(obj);
            System.out.println(methods1);
            Driver driver = new Driver();
            methods1.invoke(driver,null);
//            for (int i = 0; i < methods.length; i++) {
//                System.out.println(methods[i]);
//            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

反射JavaBean

package com.JavaBean1105;
​
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
​
public class Test {
    public static void main(String[] args) {
//        作业:给定一个java bean,获取该类的构造方法来构造对象,
//        获取该类的名称和该类中每一个方法的变量方法的名称,
//        并执行get方法。给每一个变量赋值,并获取值,执行每一个构造方法
        try {
            //获取含参构造器
            Class class1 = Class.forName("com.JavaBean1105.Body");
            Constructor constructor = class1.getDeclaredConstructor(int.class,String.class);
            constructor.setAccessible(true);
            //用含参构造器构造对象
            Object object = constructor.newInstance(1,"TheBody");
            System.out.println("构造方法构造:"+object);
            System.out.println("获取类的名称"+class1.toString());
            Method[] methods = class1.getDeclaredMethods();
            System.out.println("获取所有方法");
            Constructor[] constructors = class1.getDeclaredConstructors();
            for (int i = 0; i < constructors.length; i++) {
                System.out.println("构造方法["+(i+1)+"] "+constructors[i]);
            }
            for (int i = 0; i < methods.length; i++) {
                System.out.println("非构造方法["+(i+1)+"] "+methods[i]);
            }
            System.out.println("------------------------------------------------------");
            //获得无参构造器
            Constructor constructornull = class1.getDeclaredConstructor(null);
            constructornull.setAccessible(true);
            //用无参构造器构造空对象  objectnull Setter 和 Getter都可以用
            Object objectnull = constructornull.newInstance(null);
            //获得Setter
            Method method = class1.getDeclaredMethod("setId",int.class);
            Method method1 = class1.getDeclaredMethod("setName",String.class);
            method.setAccessible(true);
            method1.setAccessible(true);
            method.invoke(objectnull,123);
            method1.invoke(objectnull,"空对象setter");
            System.out.println("private Setter: "+objectnull.toString());
            System.out.println("------------------------------------------------------");
            Method method2 = class1.getDeclaredMethod("getId",null);
            Method method3 = class1.getDeclaredMethod("getName",null);
            method2.setAccessible(true);
            method3.setAccessible(true);
            System.out.println("private Getter id:  "+method2.invoke(objectnull,null));
            System.out.println("private Getter name:  "+method3.invoke(objectnull,null));
            System.out.println("------------------------------------------------------");
            Method method4 = class1.getDeclaredMethod("toString1",null);
            method4.setAccessible(true);
            System.out.println("private String toString1():    "+method4.invoke(objectnull,null));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}
​

 

db.properties

   Properties properties = new Properties();
        ClassLoader classLoader = FrameUtil.class.getClassLoader();
        InputStream inputStream = classLoader.getResourceAsStream("db.properties");
        properties.load(inputStream);
        String classname = properties.getProperty("classname");
        System.out.println(classname);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值