码迷,mamicode.com
首页 > 编程语言 > 详细

Java反射

时间:2018-05-06 15:00:07      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:我不知道   执行   member   default   结构   构造器   null   super   完整   

在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。

程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。
Perl、Python、Ruby是动态语言;C++、Java、C#不是动态语言。
Java程序可以加载一个运行时才得知名称的class,获悉其完整构造,并生成其对象实体,或对其fields设值,或唤起其methods。
反射主要有两个重要功能:
1.可以通过反射机制发现对象的类型,发现类型的方法、属性、构造器。
2.可以创建对象并访问任意对象方法和属性等。

Class类的实例表示正在运行的Java应用程序的类和接口。
通过Class实例可以获取某个类的属性(Field)、构造器(Constructor)、方法(Method)。
程序可以通过Method对象来执行对应的方法,通过Constructor对象来调用对应的构造器创建实例,能通过Field对象直接访问并修改对象的属性值。

1.反射相关的主要API

  • java.lang.Class
  • java.lang.reflect.Method
  • java.lang.reflect.Field
  • java.lang.reflect.Constructor

Class类与java.lang.reflect类库一起对反射的概念进行了支持。该类库包含了Field、Method以及Constructor类(每个类都实现了Member接口)。这些类型的对象是由JVM在运行时创建的。

2.通过反射机制获取类的三种方法

每个类都有一个Class对象。
一旦某个类的Class对象被载入内存,它就被用来创建这个类的所有对象。

2.1 Class.forName()

Class.forName()是取得Class对象的引用的一种方法。
只要你想在运行时使用类型信息,就必须首先获得对恰当的Class对象的引用。
使用Class.forName(),你不需要为了获得Class引用而持有该类型的对象。

class Candy {
  static { System.out.println("Loading Candy"); }
}

class Gum {
  static { System.out.println("Loading Gum"); }
}

class Cookie {
  static { System.out.println("Loading Cookie"); }
}

public class SweetShop {
  public static void main(String[] args) {  
    System.out.println("inside main");
    new Candy();
    System.out.println("After creating Candy");
    try {
      Class.forName("Gum");
    } catch(ClassNotFoundException e) {
      System.out.println("Couldn't find Gum");
    }
    System.out.println("After Class.forName(\"Gum\")");
    new Cookie();
    System.out.println("After creating Cookie");
  }
}

输出结果:

inside main
Loading Candy
After creating Candy
Loading Gum
After Class.forName("Gum")
Loading Cookie
After creating Cookie

注意:在传递给Class.forName()的字符串中,你必须使用全限定名(包含包名)。

2.2 getClass()

如果你已经拥有一个类型的对象,那就可以通过调用getClass()方法来获取Class引用了。

package typeinfo.toys;

interface HasBatteries {}
interface Waterproof {}
interface Shoots {}

class Toy {
  // Comment out the following default constructor
  // to see NoSuchMethodError from (*1*)
  Toy() {}
  Toy(int i) {}
}

class FancyToy extends Toy
implements HasBatteries, Waterproof, Shoots {
  FancyToy() { super(1); }
}

public class ToyTest {
  static void printInfo(Class cc) {
    System.out.println("Class name: " + cc.getName() +
      " is interface? [" + cc.isInterface() + "]");
    System.out.println("Simple name: " + cc.getSimpleName());
    System.out.println("Canonical name : " + cc.getCanonicalName());
  }
  public static void main(String[] args) {
    Class c = null;
    try {
      c = Class.forName("typeinfo.toys.FancyToy");
    } catch(ClassNotFoundException e) {
      System.out.println("Can't find FancyToy");
      System.exit(1);
    }
    printInfo(c);   
    for(Class face : c.getInterfaces())
      printInfo(face);
    Class up = c.getSuperclass();
    Object obj = null;
    try {
      // Requires default constructor:
      obj = up.newInstance();
    } catch(InstantiationException e) {
      System.out.println("Cannot instantiate");
      System.exit(1);
    } catch(IllegalAccessException e) {
      System.out.println("Cannot access");
      System.exit(1);
    }
    printInfo(obj.getClass());
  }
}

输出结果:

Class name: typeinfo.toys.FancyToy is interface? [false]
Simple name: FancyToy
Canonical name : typeinfo.toys.FancyToy
Class name: typeinfo.toys.HasBatteries is interface? [true]
Simple name: HasBatteries
Canonical name : typeinfo.toys.HasBatteries
Class name: typeinfo.toys.Waterproof is interface? [true]
Simple name: Waterproof
Canonical name : typeinfo.toys.Waterproof
Class name: typeinfo.toys.Shoots is interface? [true]
Simple name: Shoots
Canonical name : typeinfo.toys.Shoots
Class name: typeinfo.toys.Toy is interface? [false]
Simple name: Toy
Canonical name : typeinfo.toys.Toy

下面的代码片段就是通过getClass()来获取Class引用的。
技术分享图片

技术分享图片

Class的newInstance()方法表明:“我不知道你的确切类型,但是无论如何要正确地创建你自己”。
使用newInstance()来创建的类,必须带有默认的构造器。

2.3 使用类字面常量来生成对Class对象的引用(例如 Example.class)

3.获取某个类的所有构造方法

4.获取某个类的所有属性信息

5.获取某个类的所有方法信息

6.动态代理

7.空对象

8.接口与类型信息

Java反射

标签:我不知道   执行   member   default   结构   构造器   null   super   完整   

原文地址:https://www.cnblogs.com/gzhjj/p/8997984.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!