Я получаю 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;
}
});
}
}
Во-первых, вам нужно понять, почему в первую очередь стоит реализовать 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
. То есть поля не «автоматически повторяются через ", вы должны вручную и намеренно добавить все поля, которые должны считаться релевантными для равенства объектов.