码迷,mamicode.com
首页 > 编程语言 > 详细

java 类加载器、反射

时间:2018-06-29 23:34:54      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:add   ring   私有   类型   擦除   代码   etc   instance   method   

 

字节码对象,当我们保存后程序产生的.class文件是编译后的文件,当我们运行程序的时候,程序去读取.class文件,这个文件会存到内存中,在堆中创建一个.class文件对象

当程序要使用某个类的时候,该类还没有到内存中去,会通过加载,连接,初始化3步对这个类进行初始化

加载,将class文件对象加载到内存中去,创建一个class对象,任何类在被使用时都会创一个class对象

连接,1.检验,检查语法是否有问题,跟其他类是否协调

  2.准备,给静态成员变量初始化值

  3.解析,将符号引用改成直接引用

例如:int a = 1;解析就是把a直接改成1了

类什么时候初始化

1.创建类的时候

2.类的静态方法

3.类的静态成员变量赋值的时候

4.反射创建某个类的时候

5.调用某个类的子类的时候

6.直接运行程序的时候

类的加载器组成

技术分享图片

反射

 对于java中任意一个类,我们可以知道他的方法和属性,对于任意一个对象,我们可以调用他的方法和属性,解剖出来,这叫做java的反射机制

 首先我们要获取这个类的字节码对象,对他进行操作

有3种方式

我们先创建一个类person

 1 package com.orcale.damo01;
 2 
 3 public class Person {
 4     public String name;
 5     private int age;
 6     static{
 7         System.out.println("静态代码块");
 8     }
 9     public Person(){
10         System.out.println("空参构造");
11     }
12     public Person(String name,int age){
13         this.name= name;
14         this.age= age;
15         System.out.println("有参构造");
16     }
17     private Person(int age,String name){
18         this.age = age;
19         this.name= name;
20         System.out.println("有参构造");
21     }
22     public void eat(){
23         System.out.println("吃饭");
24     }
25     public void work(String name){
26         System.out.println(name+"走路");
27     }
28     private void run(String name){
29         System.out.println(name+"跑步");
30     }
31     @Override
32     public String toString() {
33         return "Person [name=" + name + ", age=" + age + "]";
34     }
35 }

通过对象获取字节码对象

1 Person p = new Person();
2 Class c = p.getClass();
  System.out.println(c);

通过类名获取

1 Class c1 = Person.class;

通过class的静态方法获取forName(完成的类名,包名)

1 Class c2 = Class.forName("com.orcale.damo01.Person");
2 System.out.println(c2);

获取公共的构造方法

1 Class c = Person.class;
2 Constructor con =c.getConstructor(这里如果是有参构造就写参数);
就表示为
 Constructor con =c.getConstructor(Sting.calss,int.class)数据类型在前,class在后面,具体看构造参数
3 System.out.println(con);

获取所有的公共的构造方法

1     Class c = Person.class;
2         Constructor[] con = c.getConstructors();   一个对象数组,把所有的构造方法都放进去
3         for(Constructor co:con){
4             System.out.println(co);
5         }

技术分享图片

获取公共的方法

1 Class c = Person.class;
2         Constructor con =c.getConstructor(String.class,int.class);
3         //因为Person类中没有单独String name的构造方法,所以写了2个,
4         Object obj = c.newInstance();
5         //创建一个对象祖宗类,然后用字节码对象获取方法
6         //getMethod("第一个写需要调用的方法名字",写需要传入的参数);
7         Method me = c.getMethod("work", String.class);
8         //调用方法用invoke方法(第一个写对象,第二个写需要传入的实参)
9         me.invoke(obj, "小明");

技术分享图片

获取所有的公共方法和获取所有的公共构造方法差不多,整个数组遍历就可以了

获取所有的公共成员变量

1 Class c= Person.class;
2         Field[] f= c.getFields();  //通过Field【】方法数组
3         for(Field ff:f){
4             System.out.println(ff);
5         }

获取指定的公共成员变量

1 Class c= Person.class;
2         Field f= c.getField("name");
3         System.out.println(f);

修改公共的成员变量赋值

1 Class c= Person.class;
2         Field f= c.getField("name");
3         Object obj = c.newInstance();
4         //调用set方法对name赋值,然后输出对象的属性
5         f.set(obj, "小明");
6         System.out.println(obj)

技术分享图片

获取私有的构造方法

原理是通过setAccessible方法,避开了对类的加载器对类的检查,不建议对私有的构造方法和属性操作,不然还私有干啥没有意义了

1     Class c =Person.class;
2         Constructor con = c.getDeclaredConstructor(int.class,String.class);
3         con.setAccessible(true);//暴力反射开关
4         Object obj =  con.newInstance(12,"dd");   
5         System.out.println(obj);

获取私有的成员变量

Class c= Person.class;
        Field field = c.getDeclaredField("age");  //获取私有的的成员变量
        Object obj = c.newInstance();
        field.setAccessible(true);  //暴力开关
        field.set(obj, 11);   
        System.out.println(obj);

 练习:有一个AarrayList<String> list,然后往里面添加int类型数据,泛型擦除(字节码文件中没有泛型)

1 ArrayList<String> arr = new ArrayList<String>();
2         arr.add("abc");
3         Class c= arr.getClass();
4         Method addd = c.getMethod("add", Object.class);
5         addd.invoke(arr, 1);
6         for(Object obj:arr){
7             System.out.println(obj);
8         }

 

java 类加载器、反射

标签:add   ring   私有   类型   擦除   代码   etc   instance   method   

原文地址:https://www.cnblogs.com/wangrongchen/p/9242789.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!