zoukankan      html  css  js  c++  java
  • 反射(得到Class类的几种方式)

    目录:

    1)java反射机制概述

    2)理解Class类并获取Class实例

    3)类的加载与ClassLoader

    4)创建运行时类的对象

    5)获取运行时类的完整结构

    6)调用运行时类的指定结构

    一---基本概念

      Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法(即使是private的),可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键(来自 百度百科)。

    一句话概述就是利用反射,底裤都能扒出来。

    游戏外挂的原理:游戏在运行的时候,通过反射去改变运行时的参数,从而达到作弊的目的。

    正常方式:引入需要的包类名称->通过new实例化->取得实例化对象

    反射方式:实例化对象->getClass()方法->得到完整的包类名称

    加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象,通过这个对象我们可以看到类的结构。

     1 package reflection;
     2 
     3 
     4 public class test01 extends Object{
     5     public static void main(String[] args) throws ClassNotFoundException{
     6         // 通过反射获取类的class对象
     7         Class c1 = Class.forName("reflection.user");
     8         System.out.println(c1);
     9         Class c2 = Class.forName("reflection.user");
    10         Class c3 = Class.forName("reflection.user");
    11         Class c4 = Class.forName("reflection.user");
    12 
    13         //  一个类在内存中只有一个class对象
    14         // 一个类被加载后,类的整个结构都会被封装在class对象中
    15         System.out.println(c2.hashCode());
    16         System.out.println(c3.hashCode());
    17         System.out.println(c4.hashCode());
    18 
    19     }
    20 }
    21 
    22 // 实体类
    23 class user {
    24     private String name;
    25     private  int id;
    26     private  int age;
    27 
    28     public user() {
    29     }
    30 
    31     public user(String name, int id, int age) {
    32         this.name = name;
    33         this.id = id;
    34         this.age = age;
    35     }
    36 
    37     public String getName() {
    38         return name;
    39     }
    40 
    41     public void setName(String name) {
    42         this.name = name;
    43     }
    44 
    45     public int getId() {
    46         return id;
    47     }
    48 
    49     public void setId(int id) {
    50         this.id = id;
    51     }
    52 
    53     public int getAge() {
    54         return age;
    55     }
    56 
    57     public void setAge(int age) {
    58         this.age = age;
    59     }
    60 
    61     @Override
    62     public String toString() {
    63         return "user{" +
    64                 "name='" + name + '\'' +
    65                 ", id=" + id +
    66                 ", age=" + age +
    67                 '}';
    68     }
    69 }

    运行结果:无论创建多少个对象,Class的类型都只有一个

    反射的优缺点

    1)优点:可以动态创建对象和编译,灵活性大

    2)缺点:对性能有影响,我们告诉虚拟机我们要做什么,让他去干,命令下达和他完成完有一个时间延迟。直接new出来的和反射出来的差了好几十倍。

    反射主要的API:

    1)java.lang.Class:代表一个类  (记住这个)

    2)java.lang.reflect.Method: 代表类的方法

    3)java.lang.reflect.Field:代表类的成员变量

    4)java.lang.reflect.Constructor:代表类的构造器

    Class类:

    在Object类中定义了以下的方法,此方法将被所有子类继承

    1 public final native Class getClass();

    1)Class本身也是一个类

    2)Class对象只能由系统建立对象

    3)一个加载的类在JVM中只会有一个Class实例

    4)一个Class对象对应的是一个加载到JVM中的一个class文件

    5)每个类的实例都会记得自己是由哪个Class实例所生成

    6)通过Class可以完整的得到一个类中的所有被加载的结构

    7)Class是reflection的根源,针对任何你想动态加载,运行的类,唯有先获得相应的Class对象

    Class类的常用方法:

     获取Class类的实例:

    1)若已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高

    Class clazz = Person.class

    2)已知某个类的实例,调用该实例的getClass()方法获取Class()对象

    Class clazz = person.getClass()

    3)已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,

    可能抛出ClassNotFoundException

    class clazz = Class.forName("demo01.Studengt")

    4)内置基本数据类型可以 直接用类名.Type

    测试代码:

     1 package reflection;
     2 
     3 public class test02 {
     4     public static void main(String[] args) throws ClassNotFoundException {
     5         Person person = new Student();
     6         System.out.println("这个人是" + person.name);
     7         // 方式一: 通过对象获得
     8         Class c1 = person.getClass();
     9         System.out.println(c1.hashCode());
    10 
    11 
    12         // 方式二: forName获得
    13         Class c2 = Class.forName("reflection.Student");
    14         System.out.println(c2.hashCode());
    15 
    16         // 方式三: 通过类名.class获得
    17         Class c3 = Student.class;
    18         System.out.println(c3.hashCode());
    19 
    20         // 方式四: 基本内置类型的包装类都有一个Type属性
    21         Class c4 = Float.TYPE;
    22         System.out.println(c4);
    23 
    24         // 获得父类的类型(这里就是通过对象获取类)
    25         Class c5 = c1.getSuperclass();
    26         System.out.println(c5);
    27         
    28     }
    29 }
    30 
    31 class Person {
    32      String name;
    33      int age;
    34 
    35     public Person() {
    36     }
    37 
    38     public Person(String name, int age) {
    39         this.name = name;
    40         this.age = age;
    41     }
    42 
    43 }
    44 
    45 class Student extends Person {
    46     public Student() {
    47         this.name = "学生";
    48     }
    49 }
    50 
    51 class Teacher extends Person {
    52     public Teacher() {
    53         this.name = "老师";
    54     }
    55 }

    结果:

  • 相关阅读:
    PAT Basic 1077 互评成绩计算 (20 分)
    PAT Basic 1055 集体照 (25 分)
    PAT Basic 1059 C语言竞赛 (20 分)
    PAT Basic 1072 开学寄语 (20 分)
    PAT Basic 1049 数列的片段和 (20 分)
    蓝桥杯BASIC-13 数列排序
    蓝桥杯入门——3.序列求和
    蓝桥杯入门——2.圆的面积
    蓝桥杯入门——1.Fibonacci数列
    树的总结(遍历,BST,AVL原型,堆,练习题)
  • 原文地址:https://www.cnblogs.com/YXBLOGXYY/p/14643120.html
Copyright © 2011-2022 走看看