JAVA class对象是否能作为比较值

2020-03-16  本文已影响0人  万里凪

直接说结论:可以,但是不安全(可能性其实很小)
原因是 classpath下的类通常是由AppClassLoader加载的, 如果有另外一个继承自ExtClassLoader的类加载器也加载了这些.class文件.那么class对象无论是hash也好,对象引用值也罢.都是不同的. 即: 他们会在方法区形成两个类对象.
还有一种可能是: 使用了继承自AppClassLoader的两个不同的类加载器,分别通过 findClass方法而非loadClass方法进行类加载.(loadClass会优先委派双亲,如果双亲==null才会调用findClass).

    public static void main(String[] args) throws ClassNotFoundException, MalformedURLException {
        File filpath = new File("");
        String path = "file:"+filpath.getAbsoluteFile()+"/xxx.class";
        URL newurl=new URL(path);

        TestClassLoader loader1 = new TestClassLoader(newurl.getPath());
        TestClassLoader2 loader2 = new TestClassLoader2(newurl.getPath());

        Class<?> cls1 = loader1.findClass(CloudUserDAOImpl.class.getCanonicalName());
        Class<?> cls2 = loader2.findClass(CloudUserDAOImpl.class.getCanonicalName());

        Map result = new HashMap();
        // result.put(cls1, cls1);
        // result.put(cls2, cls2);
        // result.put("equalClass", cls1 == cls2);
        result.put("hash1", cls1.hashCode());
        result.put("hash2", cls2.hashCode());

        System.out.println(result);
    }

可以使用自定义的的classloader进行测试

/**
 * @author dqy
 * @version 1.0
 * @date 2020/3/16 下午3:54
 */
public class TestClassLoader extends ClassLoader {
    //指定路径
    private String path ;


    public TestClassLoader(String classPath){
        path = classPath;
    }

    /**
     * 重写findClass方法
     * @param name 是我们这个类的全路径
     * @return
     * @throws ClassNotFoundException
     */
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        Class log = null;
        // 获取该class文件字节码数组
        byte[] classData = getData();

        if (classData != null) {
            // 将class的字节码数组转换成Class类的实例
            log = defineClass(name, classData, 0, classData.length);
        }
        return log;
    }

    /**
     * 将class文件转化为字节码数组
     * @return
     */
    private byte[] getData() {
        File file = new File(path);
        if (file.exists()){
            FileInputStream in = null;
            ByteArrayOutputStream out = null;
            try {
                in = new FileInputStream(file);
                out = new ByteArrayOutputStream();

                byte[] buffer = new byte[1024];
                int size = 0;
                while ((size = in.read(buffer)) != -1) {
                    out.write(buffer, 0, size);
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return out.toByteArray();
        } else {
            return null;
        }
    }
}

TestClassLoader2可以使用同样代码.
结果:


2020-03-16 18-12-12 的屏幕截图.png
上一篇下一篇

猜你喜欢

热点阅读