Java反射技术总结

一、概念

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
程序中一般的对象的类型都是在编译期就确定下来的,而Java反射机制可以动态地创建对象并调用其属性,这样的对象的类型在编译期是未知的。所以我们可以通过反射机制直接创建对象,即使这个对象的类型在编译期是未知的因此也被称为动态加载类反射的核心是JVM在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。

1.认识Class类

Class是一个java类,跟Java API中定义的诸如Thread、Integer类、我们自己定义的类是一样,也继承了Object(Class是Object的直接子类)。总之,必须明确一点,它其实只是个类,只不过名字比较特殊。更进一步说,Class是一个java中的泛型类型

Java.lang.Class是一个比较特殊的类,它用于封装被装入到JVM中的类(包括类和接口)的信息。当一个类或接口被装入的JVM时便会产生一个与之关联的java.lang.Class对象,可以通过这个Class对象对被装入类的详细信息进行访问。(Java中Class对象和类的实例对象是两个不同的概念,不能混淆!)(每一个类都有一个封装它的java.lang.Class类对象) 基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。 每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。

一般某个类的Class对象被载入内存,它就用来创建这个类的所有实例对象:事实上,Class对象就是用来创建类的所有的“普通”对象的。 类是程序的一部分,每个类都有一个Class对象。换言之,每当编写并且编译了一个新类,就会产生一个Class对象(恰当地说,是被保存在一个同名的.class文件中)。在运行时,当我们想生成这个类的对象时,运行这个程序的 Java虚拟机(JVM)首先检查这个类的Class对象是否已经加载。如果尚未加载,JVM就会根据类名查找.class文件,并将其载入。 一旦某个类的Class对象被载入内存,它就被用来创建这个类的所有(实例)对象.

在Java中Object是一切类的父类,那么所有类的对象实际上也都是Java.lang.Class类的实例,所以所有的对象都可以转变为Java.lang.Class类型表示。

2.获取class 对象三种方法

1、调用Object类的getClass()方法来得到Class对象,这也是最常见的产生Class对象的方法。例如:MyObject x;

Class c1 = x.getClass();

2、使用Class类的中静态forName()方法获得与字符串对应的Class对象。例如:

Class c2 = Class.forName("myObject") //MyObject 必须是接口或则类名

3、获取Class类型对象的第三个方法非常简单。如果T是一个Java类型,那么T.class就代表了匹配的类对象。例如

Class c1 = Manager.class;
Class c2 = int.class;
Class c3 = Double[].class;
//综合实例
public class test {
    public static void main(String[] args)
    {
        //三种反射方式
        /************************************/
        try {
            Class<?> h2 =Class.forName("Hello");
            //找到了封装的Class类对象.
            h2.getConstructors();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        /*************************************/
        Class<?> h = Hello.class;
        //找到了封装的Class类对象.
        h.getConstructors();
        /*************************************/
        Hello hello =new Hello();
        Class<?> c = hello.getClass();
        //找到了封装的Class类对象.
        c.getConstructors();
    }
}
3.Class类的常用方法
// 得到一个类的对象.
public T newInstance()
// 得到一个类的全部构造方法
public Constructors[] getConstructors() throws SecurityException

//得到本类中单独定义的全部属性(不包括继承的属性)
public Field[] getDeclareFields() throws SecurityException
//得到本类全部属性(public)
public Field[] getFields() throws SecurityException

//得到一个类中的全部方法
public Method[] getMethods() 
//得到一个类中自定义的方法
public Method[] getDeclareMethods() 
//返回一个method对象,并设置一个方法中的所有参数类型
public Method getMethod(String methodname, Class<?>... parameterTypes){参数类类型数组}
4.使用Class对象

要想对JVM中Class类封装的信息进行访问
通过无参构造实例化对象

Class<?> c =String.class;//也可以用forname得到class对象。
//得到class对象后,通过newInstance实例化对象。
Object str =c.newInstance();

调用有参构造实例化对象

操作时需要明确调用的构造函数,并将参数进行传递。
1.通过class类的getConstructors()取得本类中的全部构造方法
2.向构造方法传递一个对象数组进去,里面包含了构造方法所需的各个参数
3.之后通过Constructor实例化对象
Class<?> c =null;
c =Class.forNAme("org.sysu.book");
Constructor<?> cons[] =null;
cons=c.getConstructors();
Book book =(Book)cons[0].newInstance("wkn",22);

二、反射的基本运用

反射可以用于判断任意对象所属的类,获得Class对象构造任意一个对象以及调用一个对象。介绍一下基本反射功能的实现.

1 判断是否为某个类的实例
public native boolean isInstance(Object obj);
Hello hello =new Hello();
Class<?> c = hello.getClass();//找到了封装的Class类对象.
System.out.println(c.isInstance(hello));
//true
2. 创建实例

1.使用class对象的newInstance()方法创建class对象对应类的实例(默认的构造函数)

Class<?> c =String.class;
Object str =c.newInstance();

2.先通过class对象获取指定的Constructor对象(由于构造器之间的区别在于参数,故需要传入参数对应的泛型类),再调用Constructor对象的newInstance()方法创建实例,这种方法可以用指定的构造器构造类的实例

//获取String所对应的Class对象
Class<?> c = String.class;
//获取String类带一个String参数的构造器!!!!
Constructor constructor = c.getConstructor(String.class);
//根据构造器创建实例
Object obj = constructor.newInstance("wkn");
System.out.println(obj);
3.获取方法

1.getDeclaredMethods()方法返回类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。

public Method[] getDeclaredMethods() throws SecurityException

2.getMethods()方法返回某个类的所有公用(public)方法,包括其继承类的公用方法。

public Method[] getMethods() throws SecurityException

3.getMethod方法返回一个特定的方法,其中第一个参数为方法名称,后面的参数为方法的参数对应Class的对象

public Method getMethod(String name, Class<?>... parameterTypes)

4.调用方法
当我们从类中获取了一个方法后,我们就可以用invoke()方法来调用这个方法。invoke方法的原型为: 调用方法,必须传入对象实例

public Object invoke(Object obj, Object... args)
        throws IllegalAccessException, IllegalArgumentException,
           InvocationTargetException
 //obj是指定哪个对象调用,args是传入的参数.
//实例2
Hello hello1 =new Hello();
Class<?> t = hello.getClass();//找到了封装的Class类对象.
try {
  Method m = t.getMethod("method1",String.class);//method1 是方法的名字
  Hello hello2 = (Hello) t.newInstance();// Hello对象
  Object re =   m.invoke(hello2,"sss"); //反射调用方法
  System.out.println(re);
} catch (Exception e) {
  e.printStackTrace();
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java核心技术 卷II 高级特性》是对Java编程语言的进一步深入学习的一本书籍。书中主要涵盖了Java语言的一些高级特性和相关的主题。以下是对该书的简要介绍和总结。 本书分为17章,从高级I/O、网络编程和多线程编程等基础知识开始,逐步深入讲解了Java的高级特性。其中,有关泛型、集合框架、Lambda表达式、流式编程、并发、反射等内容是本书的重点。 在泛型方面,书中详细介绍了泛型的定义、使用以及泛型、泛型接口和泛型方法等。对于集合框架,书中介绍了Java集合框架的体系结构,以及常用的集合和算法。在Lambda表达式和流式编程方面,通过简洁的语法和链式操作,使得Java编程变得更为简洁和灵活。 书中还涉及了并发和多线程编程的相关知识,包括线程的创建、同步与通信、线程池以及并发集合的使用等。此外,反射也是本书的一个重要内容,反射让我们可以通过程序来动态获取的信息,以及在运行时修改的行为。 通过阅读本书,读者可以进一步提高自己的Java编程能力,了解和掌握Java语言的一些高级特性和相关知识。本书不仅适合有一定Java编程基础的开发人员阅读,也可以作为高级Java课程的教材。 总之,《Java核心技术 卷II 高级特性》这本书通过深入浅出的方式讲解了Java语言的一些高级特性和相关内容,对于想要进一步提升Java编程能力的读者来说,是一本不可多得的好书。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值