как метод equals работает внутри

Я получаю NoClassFoundError, когда классы, загруженные загрузчиком класса времени выполнения, не могут обращаться к классам, уже загруженным корневым загрузчиком java. Поскольку разные загрузчики классов находятся в разных доменах безопасности (в соответствии с java), jvm не будет разрешать классы, уже загруженные корневым загрузчиком, которые будут разрешены в адресном пространстве загрузчика.

Запустите вашу программу с помощью java -javaagent: tracer.jar [YOUR java ARGS] '

Он производит вывод, показывающий загруженный класс, и загрузчик env, который загружал класс. Очень полезно отслеживать, почему класс не может быть разрешен.

// ClassLoaderTracer.java
// From: https://blogs.oracle.com/sundararajan/entry/tracing_class_loading_1_5

import java.lang.instrument.*;
import java.security.*;

// manifest.mf
// Premain-Class: ClassLoadTracer

// jar -cvfm tracer.jar manifest.mf ClassLoaderTracer.class

// java -javaagent:tracer.jar  [...]

public class ClassLoadTracer 
{
    public static void premain(String agentArgs, Instrumentation inst) 
    {
        final java.io.PrintStream out = System.out;
        inst.addTransformer(new ClassFileTransformer() {
            public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {

                String pd = (null == protectionDomain) ? "null" : protectionDomain.getCodeSource().toString();
                out.println(className + " loaded by " + loader + " at " + new java.util.Date() + " in " + pd);

                // dump stack trace of the thread loading class 
                Thread.dumpStack();

                // we just want the original .class bytes to be loaded!
                // we are not instrumenting it...
                return null;
            }
        });
    }
}
-1
задан Slaw 16 January 2019 в 17:41
поделиться

1 ответ

Во-первых, вам нужно понять, почему в первую очередь стоит реализовать equals. Когда вы проводите сравнение примитивных типов, таких как целые числа, становится совершенно очевидно, как они сравниваются. Java не нуждается в какой-либо помощи, чтобы сказать, 1==1 Но для класса, который вы создаете сами, как Student, Java не знает, что означает равенство. Единственное, что он может проверить самостоятельно - это ссылочное равенство ; то есть, указывают ли две переменные на один и тот же объект в памяти. Однако обычно это бесполезно, поэтому вместо этого мы должны написать собственный метод и определить, когда два объекта равны, проверяя внутренние детали каждого из них. (Если вы уже все это знали, извините, но с таким же успехом можете быть внимательны)

Похоже, что ваш класс Student определил равенство как истинное, когда два Student объекта имеют одно и то же regNumber. [ 1122]

Давайте рассмотрим, что он делает, шаг за шагом:

    if (this == obj)
        return true;

this ссылается на ссылку на текущий экземпляр объекта Student, вызывающего этот метод . Другими словами, это не что иное, как указатель на объект. Таким образом, оператор if выполняет проверку, которая гласит: «Если эта ссылка на объект и ссылка на объект переданы в точке одному и тому же объекту, верните true». По сути, это избавляет нас от необходимости сравнивать какие-либо их внутренние детали, потому что, если два объекта проходят ссылочное равенство, они должны быть равны.

    if (obj == null)
        return false;

Довольно понятно. Если переданная ссылка на другой объект является нулевой, она не может быть равна этому объекту, поэтому верните false.

    if (getClass() != obj.getClass())
        return false;

Эта строка выполняет сравнение на основе типов классов. Таким образом, если этот объект (a Student) не относится к тому же типу класса, что и переданный объект, снова они не могут быть равны, поэтому возвращают false.

    Student other = (Student) obj;
    if (regNumber == null) {
        if (other.regNumber != null)
            return false;
    } else if (!regNumber.equals(other.regNumber))
        return false;
    return true;

Теперь для настоящего мяса сравнения. Сначала мы приводим переданный Object обратно в тип Student. Затем сравните regNumber каждого объекта (сначала подтвердите, что ни один из них не является null, чтобы избежать NullPointerException. Если они не равны, мы возвращаем false, в противном случае возвращаем true.

Обратите внимание, что если вы если добавить дополнительные поля в Student, они будут проигнорированы в том, что касается равенства, если только вы не добавите способ учесть их в своем методе equals. То есть поля не «автоматически повторяются через ", вы должны вручную и намеренно добавить все поля, которые должны считаться релевантными для равенства объектов.

0
ответ дан Stalemate Of Tuning 16 January 2019 в 17:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: