美文网首页
JAVA class对象是否能作为比较值

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

作者: 万里凪 | 来源:发表于2020-03-16 17:13 被阅读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

    相关文章

      网友评论

          本文标题:JAVA class对象是否能作为比较值

          本文链接:https://www.haomeiwen.com/subject/cfdnehtx.html