java反射机制高级应用-基本操作

反射概述

  • java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。
  • 对于任意一个对象,都能够调用它的任意一个方法和属性。
  • 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制
  • 要想解剖一个类,必须先要获取到该类的字节码文件对象
  • 而解剖使用的就是Class类中的方法,所以要先获取到每一个字节码文件对应的Class类型的对象

三种方式调用Class类(反射源头)

  1. Object类的getClass()方法,判断两个对象是否是同一个字节码文件
//判断是否是同一个字节码对象
//Person p = new Person();
Class clazz = p.getClass();

面试题:请解释Object类中的所有方法以及每一个方法使用上的注意事项:

  • 对象克隆:public Object clone() throws CloneNotSupportdException;

    克隆对象所在的类一定要实现java.lang.Cloneable接口,而且子类只需要继续Object类的Clone()方法就可以成功实现克隆操作
  • 对象输出:public String toString()

    直接输出对象时会默认调用toString()方法
  • 对象比较:public boolean equals(Object obj)

    当保存Set集合时,会依靠hashCode()和equals()判断是否为重复对象
  • 取得对象的hash码:public int hashCode()

    可以理解为每一个类对象的唯一编码,比较时会先判断编码是否相同,而后再调用equals()比较内容;
  • 取得Class类对象:public Class getClass();

    通过一个已经实例化好的对象进行对象的反射操作
  • 线程等待:public void wait() InterceptorException

    执行到此代码时线程要等待执行,一直到执行notify(),notifyAll()
  • 唤醒第一个等待线程:public void notify()
  • 唤醒全部等待线程:public void notifyAll();
  • 垃圾回收前释放:public void finalize() htrows Throwable;

    当使用gc回收无用垃圾空间时默认调用
  1. 静态属性Class,锁对象(Hiberate)
//当作静态方法的锁对象 
//Person.class
Class clazz = Person.class
  1. Class类中静态方法forName(),读取配置文件
//读取配置文件
//Person.java
Class clazz = class.forName("类全限定名");

利用反射实例化对象

package cn.jishuz.demo;
class Student{
    public Student() {
        System.out.println("Student类的构造方法");
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "Student类的toString()方法";
    }
}
public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class cls = Class.forName("cn.jishuz.demo.Student");
        // 相当于关键字new实例化对象,等价:Object obj = new Object();
        Object obj = cls.newInstance();
        System.out.println(obj);
    }
}

++必须要求类中存在无参构造方法,否则报错: java.lang.InstantiationException++

操作构造方法

可以解决上面实例化必须要无参构造的现象

在Class类里面定义了可以取得一个类之中构造方法的操作:

  • 取得类之中的全部构造(预先不知道构造的参数类型时可以先打印它的所有构造):public Constructor[] getConstructors()
  • 取得类之中指定参数的构造:public Constructor getConstruct(Class... parameterTypes)
package cn.jishuz.demo;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

class Student{
    private String name;
    private Integer age;
    public Student(String name,Integer age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "姓名:"+ this.name+",年龄:"+this.age;
    }
}
public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        Class cls = Class.forName("cn.jishuz.demo.Student");
        Constructor cons = cls.getConstructor(String.class,Integer.class);
        // 相当于关键字new实例化对象,等价:Object obj = new Object();
//      Object obj = cls.newInstance();
        Object obj = cons.newInstance("TOM",20);
        System.out.println(obj);
    }
}

调用类中方法

取得了类的实例化对象后就可以开始调用类中的方法。

两种类型:

- 取得父类继承而来的方法:

1.取得全部方法:

public Method[] getMethods()
                    throws SecurityException

2.获取指定方法:

public Method getMethod(String name,Class... parameterTypes)
                 throws NoSuchMethodException, SecurityException
- 取得本类定义的方法:

1.取得全部方法:

public Method[] getDeclaredMethods()
                            throws SecurityException

2.获取指定方法

public Method getDeclaredMethod(String name, Class... parameterTypes)
                         throws NoSuchMethodException, SecurityException

范例:

package cn.jishuz.demo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

interface Message{
    public void get();
}

class Student implements Message{
    @Override
    public void get() {}
    public void fun(){}
    public void print(){}
    
}
public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        Class cls = Class.forName("cn.jishuz.demo.Student");
        Method met[] = cls.getMethods();
        for(int x= 0;x

其它

取得方法修饰符:public int getModifiers();

  • 修饰符int转换为String:
    public static String toString(int mod);

取得方法的返回参数类型:public Class getReturnType();

  • getSimpleName()得到简称

取得方法的参数:public Class[] getParameterTypes();


取得所有抛出的异常:public Class[] getExceptionTypes()


++反射调用类中的方法++:public Object invoke(Object obj,Object... args)

调用类中的属性(尽量不要去使用)

支持的方法有两类:

  1. 取得所有继承而来的属性:
  • 取得全部属性:public Field[] getFields()
  • 取得指定属性:public Field getField(String name)
  1. 取得本类定义的属性:
  • 取得全部属性:public Field[] getDeclaredFields()
  • 取得指定属性:public Field getDeclaredField(String name)
package cn.jishuz.demo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

interface Message{
    public static final String INFO = "hello world.";
}
class Person{
    private String name;
    private Integer age;
}
class Student extends Person implements Message{
    private String school;
    private Double price;
}
public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        Class cls = Class.forName("cn.jishuz.demo.Student");
        {//取得继承而来的全部属性
            Field fields[] = cls.getFields();
            for(int x= 0;x

在Field类里面还定义有进行属性调用的方法:

  • 设置属性内容:public void set(Object obj,Object value)
  • 取得属性内容:public Object get(Object obj)

在Constrcutor、Method、Field三个类上有一个共同的父类AccessibleObject,在这个类里面定义了可以取消封装的方法:public void etAccessible(boolean flag);设置成true即可取消封装。


觉得还行可以点个星星哦

你可能感兴趣的:(java反射机制高级应用-基本操作)