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 }

    结果:

  • 相关阅读:
    CSS浏览器兼容----IE的定制CSS样式
    CSS浏览器兼容---判断IE版本的HTM语句
    单链表操作1
    数学建模1
    浏览器内核学习笔记二
    浏览器内核学习笔记一
    网页使用特殊字体
    SQL Server 2008 R2没有卸载干净
    RadioButtonFor绑定值
    SVN 服务启动报错 0x8007042a
  • 原文地址:https://www.cnblogs.com/YXBLOGXYY/p/14643120.html
Copyright © 2011-2022 走看看