1、静态 vs 动态语言

1.1 动态语言

  • 是一类运行时可以改变其结构的语言:例如新的函数、对象,甚至代码可以被引进,已有的函数可以被删除或者其他结构上的改变。简单的说就是运行的时候代码可以依据某些条件改变自身的结构
  • 常见的动态语言:Object-C、C#、JavaScript、Python、PHP

1.2 静态语言

  • 与动态语言对应的,运行时结构不可变的语言就是静态语言,如Java、C、C++
  • Java 不是动态语言,但也拥有一定的动态性,可以利用反射机制获得类似动态语言的特性,Java的动态性可以让我们在编程的时候更加的灵活!

2、反射Reflection

Reflection是Java提供动态语言的关键,反射机制允许程序在执行期间借助于Reflection API获取任何类的内部信息,并能够直接操作对象的内部属性和方法

  1. Class c = Class.forName("java.lang.String")

加载完类后,在堆的内存方法中就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的结构类信息。可以通过这个对象看到类的结构。对象就好比一面镜子一样,通过镜子看到类的结构,这个过程我们称之为反射

正常方式: 引入需要的”包类”名称 ——> 通过new实例化 ——> 获取实例化对象
反射方式: 实例化对象 ——> getClass()方法 ——> 得到完成的”包类”名称

3、获得反射对象

  1. // 通过反射获取类的Class对象
  2. public class Demo01 {
  3. public static void main(String[] args) throws ClassNotFoundException {
  4. Class c1 = Class.forName("reflection.User");
  5. System.out.println(c1); // class reflection.User
  6. // 一个类内存中只有一个hash对象
  7. Class c2 = Class.forName("reflection.User");
  8. System.out.println(c1.hashCode()); //460141958
  9. System.out.println(c2.hashCode()); //460141958
  10. }
  11. }
  12. // 实体类
  13. class User {
  14. private String name;
  15. private int id;
  16. private int age;
  17. // 无参构造
  18. public User() {
  19. }
  20. public User(String name, int id, int age) {
  21. this.name = name;
  22. this.id = id;
  23. this.age = age;
  24. }
  25. @Override
  26. public String toString() {
  27. return "User{" +
  28. "name='" + name + '\'' +
  29. ", id=" + id +
  30. ", age=" + age +
  31. '}';
  32. }
  33. }

4、Class类

在Object类中定义了一下方法,该方法将被所有的对象继承

  1. public final Class getClass()

上面方法的返回值类型是一个Class类,是Java反射的源头,实际上所有的反射从程序运行的角度来看就是:通过对象反射求出类的名称

4.1 Class类的获取方式

  1. package reflection;
  2. // 获取class类的创建方式
  3. public class Demo2 {
  4. public static void main(String[] args) throws ClassNotFoundException {
  5. Person person = new Student();
  6. System.out.println("这个人是: " + person.name);
  7. // 方式1:通过对象获得
  8. Class c1 = person.getClass();
  9. System.out.println(c1);
  10. // 方式2: 通过forName获得
  11. Class c2 = Class.forName("reflection.Student");
  12. System.out.println(c2);
  13. // 方式3:通过类名.class获得
  14. Class c3 = Student.class;
  15. System.out.println(c3);
  16. }
  17. }
  18. class Person {
  19. public String name;
  20. // 无参构造
  21. public Person() {
  22. }
  23. public Person(String name) {
  24. this.name = name;
  25. }
  26. @Override
  27. public String toString() {
  28. return "name" + name;
  29. }
  30. }
  31. class Student extends Person {
  32. public Student() {
  33. this.name = "学生";
  34. }
  35. }