------- android培训、java培训、期待与您交流! ----------
- Class的由来(用于表述字节码文件的类的名称就是Class)
当程序主动使用一个类时。如果该类还未加载到内存当中。则系统会通过加载,链接,初始化3个步骤来对类进行初始化,如果没有意外,JVM将会联系完成这个步骤。
而类的加载就是将类的class文件读入内存当中,并为此创建一个java.lang.Class对象,那么我们可以理解,我们在程序当中使用任何一个类时,系统都会为此创建一个java.lang.Class对象。
可以理解的就是:我们如果获取到字节码对象,就可以操作字节码对象当中的内容,这样我们不久可以动态的获取类中的内容并且使用了。
摘录:我们知道。类是一类对象的抽象,那么我们可以这样想一下,类也是一种对象,而类是一种概念层次的东西,我们说描述主要用于定义和描述其他事物,但是概念本身也需要一些描述,也就是说需要另外一个类来描述这些类的抽象,那么我们的Class类就产生了。
- JAVA程序中的类属于同一个事物,描述这类事物的类就叫Class
一个类被加载到内存当中,占用一片存储空间,这个空间里面的内容就该类字节码,不同的类的字节码是不同的,所以他们在内存中的内容也是不相同的,这一个个空间可以分别咏鹅一个个对象来表示,这些对象。
但是我们可以总结出,这些对象也会有相同的类型,这个类型就是Class类
- 基本的 Java 类型(
boolean
、byte
、char
、short
、int
、long
、float
和double
)和关键字void
也表示为Class
对象。 Class
没有公共构造方法。Class
对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass
方法自动构造的。
- 那么我们如何获得类的Class对象呢?(就是如何获取字节码对象)可以理解这是反射的核心。
我们用一段代码来演示
//获取到字节码的3种方法 String str = "zhulang"; /* * 方式一 * 使用Object类当中的getClass方法。 * 但是这个方法必须要创建未知类对象,在调用getClass方法 */ Class class1 = str.getClass(); /** * 方式二 * 使用该类的静态class属性获取。这个方式和一一样,还是要知道未知的类。 */ Class class2 = String.class; /** * 方式三。 * 通过Class类当中的静态方法 forName(String className)来完成。 * 该方法根基传入类的名称,自动去classPath路径下去寻找改名称相同的类文件 * 然后通过类加载器进行加载,并且在内存当中生成类的字节码文件对象。 */ Class class3 = Class.forName("java.lang.String"); System.out.println(class1 == class2); System.out.println(class1 == class3);
结果是
反射
反射:就是把java类中个成份映射一个Java类,包括Class,Method,Field,Constructorh和Array等等,这些类分别代表类,方法,Field,构造器和数组。
反射的由来
1.在不明确日后出现什么样的实现类是,可以扩展出去,对外提供配置文件,让后期的实现类都定义在配置文件中,
2.该程序会读取配置文件并根据指定的名字寻找对应的类。
3.找到对应的类进行对象的建立,
4.并且调用该类对象的成员,
可以说反射大大提高程序的扩展性。
- 反射字段
private void fieldDemo() throws Exception { /* * 获取获取指定类当中的指定名称的字段 * 思路:先要获取到该类的字节码文件对象 * 2.通过字节码文件对象 获取当中的成员字段 * */ String className ="com.text.Person"; //获取到 该类的字节码文件对象 Class perClass = Class.forName(className); //获取到成员字段的对象 Field field = perClass.getDeclaredField("age"); //获取到,那么我们要进行字段的设置一个值,要想设置值,那么我们得实列化一个成员对象。 Object obj = perClass.newInstance(); field.setAccessible(true); //对象也创建了,那么我们怎么给字段设置值呢? field.set(obj, 18); //我们现在来获取方法来设置字段的值 //我们来操作方法了。 System.out.println(field.get(obj)); }
- 反射构造函数演示
/** * 反射构造函数 */ private static void constructorDemo() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { //反射构造函数有什么作用。有构造函数我们就能够对构造函数进行初始化 String className = "com.text.Person"; //获得Class对象 我的理解是理解是里面包含 类里面成员映射的许多对象 Class percls = Class.forName(className); //获取Person类的构造函数的对象 Constructor con = percls.getConstructor(String.class); Person obj =(Person) con.newInstance("zhulang"); System.out.println(obj.getName());
- 反射方法
/** * 反射方法。 */ private static void MethodDemo() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException { //获取到Class集合 Class metClass = Class.forName("com.text.Person"); //那么我们要获取到方法类。 Method met= metClass.getMethod("show", null); //获取指定的对象 Object obj = metClass.newInstance(); //通过该该对象调用该方法。 met.invoke(obj,null); /* * 上面两行代码等同于 * Person per = new Person(); * per.show(); */ }
- 上面用到的类Person
public class Person { private String name; private int age ; public Person() { } public Person(String str) { this.name =str; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void show() { System.out.println("Person Show run"); } }