详解Java的isInstance(Object obj)方法:判断该对象是否是指定类的实例

  • Post category:Java

绝大多数的Java程序员朋友们都知道Java中Object类的isInstance(Object obj)方法,它是Class类中的一个方法,用于判断某个对象是否属于该Class所对应的类或其子类的实例。

方法说明

isInstance(Object obj)方法的用法非常简单,其方法签名如下:

public boolean isInstance(Object obj)

其中,obj表示待测试的对象,该方法返回一个boolean类型值,为true时表示该对象属于该Class所对应的类或其子类的实例,为false时则表示不属于。

方法应用

下面通过两个应用案例,进一步说明isInstance(Object obj)方法的应用。

案例1:使用isInstance()方法获取Class对象

首先我们有一个Animal类,并且在代码中动态加载了这个类,并且我们想要使用isInstance()方法来判断一个对象是否属于Animal的实例。首先,我们读取Animal类的字节码信息:

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Class<?> clazz = classLoader.loadClass("com.github.hcsp.demo.Animal");

其中,我们通过线程的上下文ClassLoader加载了Animal.class类对象的字节码信息。接下来,我们创建一个测试方法findFirstAnimal(Class<?> clazz)用来找到某个类或其子类的第一个实例:

public static <T> T findFirstAnimal(Class<?> clazz) throws InstantiationException, IllegalAccessException {
    Object obj = clazz.newInstance();
    if (clazz.isInstance(obj)) {
        return (T) obj;
    }
    return null;
}

在方法中,我们通过Class的newInstance()方法动态的创建了一个对象。在判断该对象是否属于我们想要获取的类或其子类的实例,从而找到第一个实例。我们可以在测试类中使用如下代码:

Animal animal = findFirstAnimal(clazz);
if (animal != null) {
    System.out.println(animal.getClass().getSimpleName());
} else {
    System.out.println("not found");
}

在运行TestAnimal类时,终端应显示Animal。

案例2:使用isInstance()方法实现AOP功能

假设我们有一个UserService类,其中包含了一些开放的业务方法,另外一个LoggingInterceptor类则可以在每次执行业务逻辑前输出日志。

我们可以通过isInstance()方法来实现AOP功能。首先我们创建UserService类:

public class UserService {
    public void addUser(String name) {
        System.out.println("add user " + name);
    }
}

接下来我们创建一个LoggingInterceptor类,用于在每次执行业务逻辑前输出日志:

public class LoggingInterceptor implements InvocationHandler {
    private Object target;

    public LoggingInterceptor(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before " + method.getName() + " executed...");
        Object result = method.invoke(target, args);
        System.out.println("after " + method.getName() + " executed...");
        return result;
    }
}

在方法调用时,我们可以通过Proxy.newProxyInstance()方法创建一个代理对象,该代理对象可以动态地调用原对象的方法。在该方法中,在原对象实例上应用LoggingInterceptor拦截器。

public class TestUserService {
    public static void main(String[] args) {
        UserService userService = new UserService();
        LoggingInterceptor interceptor = new LoggingInterceptor(userService);
        Object proxyObj = Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), interceptor);
        if (UserService.class.isInstance(proxyObj)) {
            UserService userService1 = (UserService) proxyObj;
            userService1.addUser("Tom");
        }
    }
}

在测试方法中,我们创建了一个名为proxyObj的代理对象,并向该代理对象传入了LoggingInterceptor实例。我们通过UserService.class.isInstance(proxyObj)判断代理对象是否属于UserService类或其子类的实例。在本例中,它属于并且会输出日志。

以上就是isInstance(Object obj)方法的完整攻略。