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

直接说结论:可以,但是不安全(可能性其实很小)
原因是 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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • ClassLoader翻译过来就是类加载器,普通的java开发者其实用到的不多,但对于某些框架开发者来说却非常常见...
    时待吾阅读 1,169评论 0 1
  • 转发:本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 ClassLoader翻译过来就是类加载...
    尼尔君阅读 622评论 0 1
  • 1、classLoader 类加载器,将class文件加载到JVM虚拟机内存中,使得程序可以运行。通常情况下,JV...
    helloWorld_1118阅读 2,362评论 0 2
  • 本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 ClassLoader翻译过来就是类加载器,普...
    尼尔君阅读 721评论 1 0
  • 首先声明,我是因为看了ImportNew网站上的几篇关于类加载器的文章之后,才萌生了写这篇文章的想法。所以在写这篇...
    陈安妮annie1阅读 313评论 0 1

友情链接更多精彩内容