美文网首页
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对象是否能作为比较值

    直接说结论:可以,但是不安全(可能性其实很小)原因是 classpath下的类通常是由AppClassLoader...

  • typescript 中的class

    class 用来创建对象。TS中的class与面向对象语言(java,c++)中的class就比较相似了。 内容:...

  • java 泛型方法的两种写法

    这种需要传入 类名.class(class对象)(java有两类对象,Class对象和实例对象。更多参考Java的...

  • Spring Boot 深拷贝对象

    背景 Java Class类的clone()方法默认为浅拷贝模式,只能实现Java基础类型的按值拷贝操作,对对象拷...

  • java反射reflect

    Class类 java中类是谁的对象? 类是对象,类是java.lang.Class类的实例对象(there is...

  • Object类

    方法 获取对象的Class对象引用Class getClass() 计算hash值int hashCode(...

  • JVM中class对象加载方式

    1 class对象详解 java中把生成Class对象和实例对象弄混了,更何况生成Class对象和生成instan...

  • java基础:深入理解Class对象与反射机制

    其他更多java基础文章:java基础学习(目录) 深入理解Class对象 RRIT及Class对象的概念 RRI...

  • 4.v-bind以及class与style的绑定

    4.1.绑定class 的几种方式 4.1.1.对象语法 绑定class对象语法:对象的键是类名,值是布尔值 当 ...

  • 比较

    java中,==号在比较基本数据类型时比较的是值,比较两个对象时比较的是两个对象的地址值 String类中的equ...

网友评论

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

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