2019独角兽企业重金招聘Python工程师标准>>>
我们在编写JAVA程序的时候,创建一个对象JVM是怎样来找到,理解并编译到.class中的?那我们就来看看在编译中Class对象的伟大魅力;好了,废话不多说,直接上干货:
1: 首先,我们来创建一个对象,方便我们测试:
package entity;/***@description TODO 测试对象*@date 2018年1月1日*@author geYang**/
public class Person {/*** 姓名*/private String name;/*** 年龄*/private int age;/*** 住址*/private String address;public Person() {}public Person(String name, int age, String address) {this.name = name;this.age = age;this.address = address;}public static void printInfo(){System.out.println("静态方法调用");}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + ", address=" + address + "]";}}
2: 测试Class的用法:
package reflex;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;/***@description TODO Class类对象的简单测试*@date 2018年1月1日*@author geYang**/
public class ClassTest {/*** 运行时类型信息使得我们可以在程序运行时发现和使用类型信息;而类型信息使我们从只能在编译期执行面向类型的操作的禁锢中解脱出来;* 并且可以使用某些非常强大的程序;* * JAVA是如何让程序在运行时识别对象和类的信息的.主要有两种方法:* 1: "传统的" RTTI : 它假定我们在编译时已经知道的需要的类型信息;* 2: "反 射" 机制 : 它允许我们在运行时发现和使用类的信息;* * 注: 运行时类型识别(RTTI, Run-Time Type Identification)是Java中非常有用的机制* ,在Java运行时,RTTI维护类的相关信息.多态(polymorphism)是基于RTTI实现的.RTTI的功能主要是由Class类实现的.* * Class 对象:* 要理解RTTI在JAVA中的工作原理,首先必须知道类型信息在运行时时如何表示的,这项工作是由称为Class对象的特殊对像完成的;* 事实上Class对象就是用来创建类的所用的"常规"对象的.Java使用Class对象来执行其RTTI; * 类是程序的一部分,每个类都有一个Class对象.每当编写或编译一个新的类时都会产生一个新的对象(被保存在其.class文件中).* 为了生成这个类的对象,运行这个程序的JVM将被称为"类加载器"的子系统;* 所有的类都是在对其第一次使用时,动态的加载到JVM中的.当程序创建第一个对类的静态成员的引用时,就会加载这个类.这证明构造器也是类的静态方法;* 即使没有使用static,所以使用new操作符创建类的新对象也会被当做对类的静态成员的引用;* 因此Java程序在其开始运行之前,并非是被完全加载,其各个部分是在必须时才加载的;动态加载也是Java的一大特性;* * 使用中类加载器首先检查这个类的Class对象是否已经被加载.如果尚未加载,默认的类加载器就会根据类名查找.class文件.这个类的字节码被加载时,* 它们会接受验证,以确保没有被破坏;一担某个类的Class被载入内存,它就会用来创建这个类的所有对象.* * 下面就来测试Class的用法:* @throws ClassNotFoundException * @throws SecurityException * @throws NoSuchFieldException * @throws NoSuchMethodException * @throws InvocationTargetException * @throws IllegalArgumentException * @throws IllegalAccessException * @throws InstantiationException **/public static void main(String[] args) throws Exception {/* (举个例子啊) 假设我们当前并不知道String类是干什么的,但我们只知道有 "java.lang.String" 这个名字,那么怎么来获取String对象呢? *///Class<?> clazz = Class.forName("java.lang.String");//换成其他也一样Class<?> clazz = Class.forName("entity.Person");/* 要抛个找不到的错,打印一下=>结果:"class java.lang.String" (没有报错)证明有这个类*/System.out.println(clazz);/* 2,光有类也没用,我还想看看他下面有什么属性 */System.out.println("================= 所有属性 =====================");Field[] fields = clazz.getDeclaredFields();//获取到一个 Field 对象的数组(证明,类中的属性也都是一个对象),打印一下:for(Field field : fields){System.out.println(field);}System.out.println("================= 单一属性 =============");Field field = clazz.getDeclaredField("name");System.out.println(field);/* 3,获取类的方法 */System.out.println("================= 所有方法 =====================");Method[] methods = clazz.getDeclaredMethods();for(Method method : methods){System.out.println(method);}System.out.println("========= 单一方法(无参) =========");Method method = clazz.getDeclaredMethod("getName", new Class[]{});System.out.println(method);System.out.println("========= 单一方法(有参) =========");Method method2 = clazz.getDeclaredMethod("setName", new Class[]{String.class});System.out.println(method2);/* 3,获取类的构造器 */System.out.println("================= 所有构造器 =====================");Constructor<?>[] constructors = clazz.getDeclaredConstructors();for(Constructor<?> constructor : constructors){System.out.println(constructor);}System.out.println("======== 单一构造器(无参) =======");Constructor<?> constructor = clazz.getDeclaredConstructor(new Class[]{});System.out.println(constructor);System.out.println("======== 单一构造器(有参) =======");Constructor<?> constructor2 = clazz.getDeclaredConstructor(new Class[]{String.class,int.class,String.class});System.out.println(constructor2);/*4, 根据类的的构造器来获取对象*/System.out.println("================= 对象(无参) =====================");Object object = constructor.newInstance(new Object[]{});System.out.println(object);System.out.println("================= 对象(有参) =====================");Object object2 = constructor2.newInstance(new Object[]{"张三",18,"绵阳"});System.out.println(object2);}}
做了上面的测试,那么对于Class对象已经有了初步的了解;
参考: https://ke.qq.com/course/180327