秒速pk10彩票app _Java匹马行天下之JavaSE核心技术——反射机制

  • 时间:
  • 浏览:1

    在运行请况中,对于任意一个多 类,都也能获取到你你这个 类的所有属性和最好的辦法 ,对于任意一个多 对象,都也能调用它的任意一个多 最好的辦法 和属性(包括私有的最好的辦法 和属性),你你这个 动态获取的信息以及动态调用对象的最好的辦法 的功能就称为java语言的反射机制。通俗点讲,通过反射,该类对一帮人儿来说是完整版透明的,要我获取任何东西都可不上能。

    要我使用反射机制,就必里可不上能 先获取到该类的字节码文件对象(.class),通过字节码文件对象,就也能通过该类中的最好的辦法 获取到一帮人儿要我的所有信息(最好的辦法 ,属性,类名,父类名,实现的所有接口等等),每一个多 类对应着一个多 字节码文件也就对应着一个多 Class类型的对象,也要是我我字节码文件对象。

JAVA反射机制是在运行请况中,

  对于任意一个多 类,都也能知道你你这个 类的所有属性和最好的辦法 (动态获取的信息);

  对于任意一个多 对象,都也能调用它的任意一个多 最好的辦法 和属性(动态调用对象的最好的辦法 );

  你你这个 动态获取的信息以及动态调用对象的最好的辦法 的功能称为java语言的反射机制

  简言之:通过字节码文件对象,去使用该文件中的成员变量、构造最好的辦法 、成员最好的辦法 。

    获取字节码文件对象的并也有最好的辦法 。

       1、Class class1 = Class.forName("全限定类名");  //通过Class类中的静态最好的辦法 forName,直接获取到一个多 类的字节码文件对象,此时该类还是源文件阶段,并这么变为字节码文件。

       2、Class class2  = Person.class;    //当类被加载成.class文件时,此时Person类变成了.class,在获取该字节码文件对象,也要是我我获取当时人, 该类占据 字节码阶段。

       3、Person p = new Person();

                              Class class3 = p.getClass();    //通过类的实例获取该类的字节码文件对象,该类占据 创建对象阶段 

第并也有和后并也有的区别        
        后并也有你里可不上能


明确Person类型。
        第并也有里可不上能


你你这个

类型的字符串就行(开发中用)。
        你你这个

扩展更强,可不上能

可不上能


知道具体的类,只提供字符串,按照配置文件加载就可不上能了。

 反射的特点:

        1.Class类中的静态最好的辦法 forName()传入的字符串将来会做成配置信息文件,全都事先你我想知道多多多线程 运行的是谁(是哪个类)        2.反射是不用看完类的任何信息的。即通过构造最好的辦法 对象Constructor、成员最好的辦法 对象Method,调用一帮人的最好的辦法 返回值还会 Object类型。          (因为任何类型都可不上能用Object类型接收,基本数据类型会自动装箱为引用数据类型)。        3.反射可不上能访问私有的东西(前提是class文件未被加密)。

并也有获取字节码文件对应的Class类型的对象的最好的辦法

  要想解剖一个多 类,里可不上能 好难获取到该类的字节码文件对象。

  而解剖使用的要是我我Class类中的最好的辦法 ,全都好难获取到每一个多 字节码文件对应的Class类型的对象。

  .class文件   --> Class类

    成员变量    --> Field类    构造最好的辦法    --> Constructor类    成员最好的辦法    --> Method类

    有了字节码文件对象也能获得类中所有的信息,一帮人儿在使用反射获取信息时,也要考虑使用上方哪种最好的辦法 获取字节码对象合理,视不同请况而定。下面介绍Class类的功能。

实例一:

package com.my.fanshe;
 2 
 3 public class Person {
 4     private String name;
 5     int age;
 6     public String address;
 7 
 8     public Person() {
 9     }
10 
11     private Person(String name) {
12         this.name = name;
13     }
14 
15     Person(String name, int age) {
16         this.name = name;
17         this.age = age;
18     }
19 
20     public Person(String name, int age, String address) {
21         this.name = name;
22         this.age = age;
23         this.address = address;
24     }
25 
26     public void show() {
27         System.out.println("show");
28     }
29 
300     public void method(String s) {
31         System.out.println("method " + s);
32     }
33 
34     public String getString(String s, int i) {
35         return s + "---" + i;
36     }
37 
38     private void function() {
39         System.out.println("function");
40     }
41 
42     @Override
43     public String toString() {
44         return "Person [name=" + name + ", age=" + age + ", address=" + address + "]";
45     }
46 
47 }

package com.my.fanshe;


/* 4 * 反射:要是我我通过class文件对象,去使用该文件中的成员变量,构造最好的辦法 ,成员最好的辦法 。 5 * 6 * Person p = new Person(); 7 * p.使用; 8 * 9 * 要想要是我我 使用,首先你里可不上能 得到class文件对象,我我其实也要是我我得到Class类的对象。 10 * .class文件 --> Class类 11 * 成员变量 --> Field类 12 * 构造最好的辦法 --> Constructor类 13 * 成员最好的辦法 --> Method类 14 * 15 * 获取class文件对象的最好的辦法 : 16 * A:Object类的getClass()最好的辦法 17 * B:数据类型的静态属性class(任意数据类型都具备一个多 class静态属性) 18 * C:Class类中的静态最好的辦法 (将类名作为字符串传递给Class类中的静态最好的辦法 forName) 19 * public static Class forName(String className) 20 * 21 * 一般一帮人儿到底使用谁呢? 22 * A:当时人玩 任选并也有,第二种比较方便 23 * B:开发时 第并也有 24 * 怎么 会 呢?因为第并也有是一个多 字符串,而还会 一个多 具体的类名。要是我我 一帮人儿就可不上能把要是我我 的字符串配置到配置文件中。 25 */ 26 public class ReflectDemo { 27 public static void main(String[] args) throws ClassNotFoundException { 28 // 最好的辦法 A 29 Person p = new Person(); 300 Class c = p.getClass(); 31 32 Person p2 = new Person(); 33 Class c2 = p2.getClass(); 34 35 System.out.println(p == p2); // false 36 System.out.println(c == c2); // true 37 38 // 最好的辦法 B 39 Class c3 = Person.class; 40 // int.class; 41 // String.class; 42 System.out.println(c == c3); // true 43 44 // 最好的辦法 C 45 // ClassNotFoundException 里可不上能 类的全路径(带包名的路径) 46 Class c4 = Class.forName("com.my.fanshe.Person"); 47 System.out.println(c == c4); // true 48 } 49 }

实例二:

package com.my.fanshe;

public interface JieKou {
    public void print();
}
package com.my.fanshe;

public class A implements JieKou {
    private String name;
    private int age;

    public A(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }


    @Override
    public void print() {

        System.out.println("实现A接口最好的辦法

");
    }

    @Override
    public String toString() {
        return "A{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public int getAge() {
        return age;
    }
}
package com.my.fanshe;

public class B implements JieKou {

    @Override
    public void print() {
        System.out.println("实现B接口最好的辦法

");
    }
}
package com.my.fanshe;

public class C {
    public void show(){
        System.out.println("实现C最好的辦法

");
    }
}
package com.my.fanshe;

public class FansheDemo {
    public static void main(String[] args) throws Exception{
        //最好的辦法

一:通过对象获得Class类类型(静态加载)
        A a = new A("张三",20);
        Class c = a.getClass();
        System.out.println("Class类类型为:"+c);
        //最好的辦法

二:通过类名获得Class类类型
        Class c1 = B.class;
        System.out.println("Class类类型为:"+c1);
        //最好的辦法

三:通过动态加载
        Class c2 = Class.forName("com.my.fanshe.C");
        System.out.println("Class类类型为:"+c2);
    }
}
运行结果:

Class类类型为:class com.my.fanshe.A
Class类类型为:class com.my.fanshe.B
Class类类型为:class com.my.fanshe.C

2、获取类的信息

package com.my.fanshe;

public interface JieKou {
    public void print();
}
package com.my.fanshe;

public class A implements JieKou {
    public String name;
    private int age;

    public A(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }


    @Override
    public void print() {

        System.out.println("实现A接口最好的辦法

");
    }

    @Override
    public String toString() {
        return "A{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public int getAge() {
        return age;
    }

}
package com.my.fanshe;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class FansheDemo {
    public static void main(String[] args) throws Exception{
        //动态加载类,Class是表示当前类的类类型
        //获取字节码文件
        Class c = Class.forName("com.my.fanshe.A");
        // 通过Class类类型获得类的实例
        Constructor constructor = c.getConstructor(String.class,int.class);
        A a = (A)constructor.newInstance("张三",20);
        //获取公共属性的成员变量
        Field f = c.getField("name");
        System.out.println(f.get(a));
        //获取私有属性的成员变量
        Field f1 = c.getDeclaredField("age");
        System.out.println(f1.getType()+" "+f1.getName());
        //打开权限
        f1.setAccessible(true);
        System.out.println(f1.get(a));
        //获取最好的辦法

并执行
        Method method = c.getMethod("getName");
        System.out.println(method.invoke(a));

        Method method1 = c.getMethod("getAge");
        System.out.println(method1.invoke(a));

        Method method2 = c.getMethod("print");
        method2.invoke(a);

        Method method3 = c.getMethod("toString");
        System.out.println(method3.invoke(a));




    }
}
运行结果:

张三
int age
20
张三
20
实现A接口最好的辦法

A{name='张三', age=20}

3、反射思维导图

1:反射(理解)
    (1)类的加载
        当多多多线程




要使用某个类时,因为该类还未被加载到内存中,则系统会通过加载连接初始化三步来实现对你你这个

类进行初始化。
        
        加载 
            要是我我指将class文件读入内存,并为之创建一个多

Class对象。
            任何类被使用时系统还会建立一个多

Class对象。
        连接
            验证:与否

有正确的内内外部特性,并和你你这个

类协调一致。
            准备:负责为类的静态成员分配内存,并设置默认初始化值。
            解析:将类的二进制数据中的符号引用替换为直接引用初始化 
            要是我我一帮人儿事先讲过的初始化步骤。
        
        注意:Object类的最好的辦法

:
                public final Class getClass()    返回对象的字节码文件对象
             Class类的最好的辦法

:
                public String getName()    以 String 的形式返回此 Class 对象所表示的实体名称。(实体包括:类、接口、数组名、基本类型或 void)
                    即:可不上能通过Class类中的一个多

最好的辦法

,获取对象的真实类的全名称
    (2)类的初始化时机
        1.创建类的实例时。
        2.访问类的静态变量,因为为静态变量赋值时。
        3.调用类的静态最好的辦法

时。
        4.使用反射最好的辦法

来强制创建某个类或接口对应的java.lang.Class对象时。
        5.初始化某个类的子类时。
        6.直接使用java.exe命令来运行某个主类时。

    (3)类加载器
        负责将.class文件加载到内存中,并为之生成对应的Class对象。
        我其实一帮人儿可不上能

可不上能


关心类加载机制,之前

了解你你这个

机制一帮人儿就能更好的理解多多多线程




的运行。
    (4)类加载器的组成
            Bootstrap ClassLoader     类加载器
            Extension ClassLoader     扩展类加载器
            Sysetm ClassLoader        系统类加载器
        
        Bootstrap ClassLoader     类加载器
            也被称为引导类加载器,负责Java核心类的加载。
            比如System类,String类等。在JDK中JRE的lib目录下rt.jar文件中(JDK8事先版本中的位置,JDK9/10位置变化了)。
            
        Extension ClassLoader     扩展类加载器
            负责JRE的扩展目录中jar包的加载。
            在JDK中JRE的lib目录下ext目录。
            
        Sysetm ClassLoader        系统类加载器
            负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径。
            一般一帮人儿当时人写的类通过系统类加载器来加载的。