zoukankan      html  css  js  c++  java
  • java反射机制详解

    反射就是在程序运行中,动态的创建对象,只要知道该类的名称,就能用它的字节码对象创建该类的对象(实例) 从而访问该类的任何方法和属性(暴力访问)

    • 什么是字节码对象?

    javac 编译java文件后得到的class文件就是该类的字节码文件

    javac Person.java//得到---------Person.class文件
    • 获得字节码的几种方法:

    1.Object类的getclass方法------构造函数私有时无法new
    2.类.class
    3.class类的静态方法forname("类全路径")方法

    》》》字节码对象.newinstance得到对象实例

    • 类和class对象关系

    成员变量……fields
    成员方法……methods
    构造函数……constructor

    • 具体事例:

    事例说明:

    单独一个Person类  其中属性,方法,以及构造方法都是公有,私有共存

    public class Person {
        private String name;
        public String password;
        String description;
    
        public void add(String na) {
            System.out.println("公有" + na);
        }
    
        private void find(String pass) {
            System.out.println("私有" + pass);
        }
    
        
        public Person() {
            super();
            // TODO Auto-generated constructor stub
        }
    
        private Person(String name, String password, String description) {
            super();
            this.name = name;
            this.password = password;
            this.description = description;
            System.out.println("私有的构造函数:"+name+password+description);
        }
    
    }

    1.通过反射得到fields(成员属性),就是通过反射得到Person的私有属性-------一般方法没法获得

    Class class1 =    Class.forName("cn.itcast.reflect.Person");//获得字节码对象
    
    //访问私有属性-------------fields
        
        Field[] fields=class1.getDeclaredFields();//获得多个属性  返回数组
        for (Field field : fields) {
            System.out.println(field);
        }

    结果:

    private java.lang.String cn.itcast.reflect.Person.name
    public java.lang.String cn.itcast.reflect.Person.password
    java.lang.String cn.itcast.reflect.Person.description

    2.通过反射访问methods(成员方法),通过反射得到Person的私有方法:

    注意Person类中的find(){}方法-----私有的

    private void find(String pass) {
            System.out.println("私有" + pass);
        }

    暴力访问:

    public static void main(String[] args) throws Exception {
      Class class1 = Class.forName("cn.itcast.reflect.Person");//获得字节码对象
      Person person=(Person) class1.newInstance();//创建对象实例 Method[] methods=class1.getDeclaredMethods(); for (Method method : methods) { System.out.println(method); } Method method=class1.getDeclaredMethod("find",String.class); method.setAccessible(true);//没有这个结果将报错 method.invoke(person, "12333"); }

    结果:

    public void cn.itcast.reflect.Person.add(java.lang.String)
    private void cn.itcast.reflect.Person.find(java.lang.String)
    私有12333


    3.通过反射访问constructor(构造函数)

    public static void main(String[] args) throws Exception {
    
    Class class1 =    Class.forName("cn.itcast.reflect.Person");//获得字节码对象
    
    Constructor[]  con=class1.getDeclaredConstructors();
        for (Constructor constructor : con) {
            System.out.println(constructor);
        }
        
        Constructor co=class1.getDeclaredConstructor(String.class,String.class,String.class);
        co.setAccessible(true);
        Person p=(Person) co.newInstance("da","xiao","da");
        System.out.println(p);
        
        
        }

    结果:

    private cn.itcast.reflect.Person(java.lang.String,java.lang.String,java.lang.String)
    public cn.itcast.reflect.Person()
    私有的构造函数:daxiaoda
    cn.itcast.reflect.Person@139a55
    • 与单例设计模式

    单例设计模式核心就是构造函数私有化,但是通过java反射机制可以破坏这种模式,通过反射还是可以访问私有构造函数


    》》》》》装逼小福利:静态代码块中的语句没有main方法也可以编译,但是代码块末尾加system.exit(0)

    Public Person{
      static {
          System.out.println("hello!!!");
          System.exit(0);    //这句是为了防止编译报错
    }  
    }
  • 相关阅读:
    用CSS3实现上下左右箭头
    让input框只能输入数字
    给内联元素设置宽高的几种方式
    当文本溢出包含的元素时加省略号之text-overflow
    通过box盒子模型给元素内容设置居中
    CSS3中的字体rem
    封装一个取消事件冒泡的方法
    HTML5 web workes实现多线程
    通过imeMode禁用键盘只能输入数字
    jquery的children方法和css3选择器配合使用
  • 原文地址:https://www.cnblogs.com/wangsr-suc/p/8917346.html
Copyright © 2011-2022 走看看