Почему метод clone () защищен в java.ленг.Возражаете?



какова конкретная причина, что clone() определяется как защищенных в java.lang.Object?

686   11  

11 ответов:

тот факт, что клон защищен крайне сомнительно-как и тот факт, что clone метод не объявлен в Cloneable интерфейс.

это делает метод довольно бесполезным для получения копий данных, потому что вы не можете сказать:

if(a instanceof Cloneable) {
    copy = ((Cloneable) a).clone();
}

Я думаю, что конструкция Cloneable Теперь в значительной степени рассматриваться как ошибка (ссылка ниже). Обычно я хотел бы иметь возможность делать реализации интерфейса Cloneable но не обязательно делать интерфейс Cloneable (аналогично использованию Serializable). Это не может быть сделано без размышления:

ISomething i = ...
if (i instanceof Cloneable) {
   //DAMN! I Need to know about ISomethingImpl! Unless...
   copy = (ISomething) i.getClass().getMethod("clone").invoke(i);
}

Цитата Из эффективная Java Джоша Блоха:
"Cloneable интерфейс был предназначен в качестве интерфейса mixin для объектов, чтобы объявить, что они разрешают клонирование. К сожалению, он не служит этой цели ... Это очень нетипичное использование интерфейсов и не один для эмуляции ... По порядку для реализации интерфейса, чтобы иметь никакого влияния на класс, он и все его суперклассы должны подчиняться довольно сложный, неисполнимый и в значительной степени недокументированный протокол"

клонируемый интерфейс-это просто маркер, говорящий, что класс может поддерживать клонирование. Метод защищен, потому что вы не должны вызывать его на object, вы можете (и должны) переопределить его как public.

От Солнца:

в объекте класса метод clone () объявляется защищенным. Если все, что вы делаете, это реализовать Cloneable, только подклассы и члены одного пакета смогут вызвать clone() на объекте. Чтобы разрешить любому классу в любом пакете доступ к методу clone() , вам придется переопределить его и объявить его общедоступным, как это сделано ниже. (При переопределении метода можно сделать его менее закрытым, но не более закрытым. Здесь защищенный метод clone () в объекте переопределяется как открытый метод.)

clone защищен, потому что это то, что должно быть переопределено, чтобы оно было специфичным для текущего класса. Пока можно было бы создать паблик clone метод, который клонировал бы любой объект, вообще это было бы не так хорошо, как метод, написанный специально для класса, который в нем нуждается.

метод Clone не может быть непосредственно использован для любого объекта, поэтому он должен быть переопределен подклассом.

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

способ реализации clone прямо сейчас заставляет вас задуматься о том, почему вы хотите использовать clone, и как вы хотите, чтобы ваш объект был клонирован.

он защищен, потому что реализация по умолчанию делает мелкую копию всех полей (включая private), конструктор обход. Это не то, что объект может быть разработан для обработки в первую очередь (например, он может отслеживать созданные экземпляры объекта в общем списке или что-то подобное).

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

из javadoc cloneable.

* By convention, classes that implement this interface (cloneable) should override 
* <tt>Object.clone</tt> (which is protected) with a public method.
* See {@link java.lang.Object#clone()} for details on overriding this
* method.

* Note that this interface does <i>not</i> contain the <tt>clone</tt> method.
* Therefore, it is not possible to clone an object merely by virtue of the
* fact that it implements this interface.  Even if the clone method is invoked
* reflectively, there is no guarantee that it will succeed.

таким образом, вы можете вызвать clone для каждого объекта, но это даст вам большую часть времени не те результаты, которые вы хотите, или исключение. Но это только рекомендуется, если вы реализуете клонируемые.

ИМХО это так просто:

  • #clone не должен вызываться на неклонируемых объектах, поэтому он не публикуется
  • #clone должен вызываться подклассами ob Object что реализовать Cloneable, чтобы получить мелкую копию правильного класса

какова правильная область для методов, которые должны вызываться подклассами, но не другими классами?

Это protected.

классов, реализующих Cloneable of курс сделает этот метод общедоступным, чтобы его можно было вызвать из других классов.

Clone() метод имеет проверку внутренне 'экземпляр Cloneable или нет'.Это то, как команда Java могла бы подумать, ограничит неправильное использование метода clone ().метод clone () защищен, т. е. доступен только подклассами. Поскольку объект является родительским классом всех подклассов, поэтому метод Clone () может использоваться всеми классами infact, если у нас нет выше проверки "экземпляра Cloneable". Именно по этой причине команда Java, возможно, решила ограничить неправильное использование clone (), выполнив регистрацию метод clone () 'является ли он экземпляром Cloneable'.

следовательно, любые классы, реализующие cloneable, могут использовать метод clone () класса объекта.

кроме того, поскольку он защищен, он доступен только для тех подклассов,которые реализуют интерфейс cloneable. Если мы хотим сделать его общедоступным,этот метод должен быть переопределен подклассом с их собственной реализацией.

да, та же проблема, что я встретил. Но я решаю ее, реализуя этот код

public class Side implements Cloneable {
    public Side clone() {

        Side side = null;
        try {
            side = (Side) super.clone();
        } catch (CloneNotSupportedException e) {
            System.err.println(e);
        }
        return side;
    }
}

Так же, как раньше кто-то сказал.

Ну, также разработчики sun являются только людьми, и они действительно сделали огромную ошибку, чтобы реализовать метод клона как защищенный, ту же ошибку, что и они реализовали нефункционирующий метод клона в ArrayList! Таким образом, в целом существует гораздо более глубокое непонимание даже опытных Java-программистов о методе клонирования.

однако недавно я нашел быстрое и простое решение для копирования любого объекта со всем его содержимым, независимо от того, как он построен и что он содержит, смотрите мой ответ здесь:ошибка в использовании объекта.clone ()

опять же, Java JDK framework показывает блестящее мышление:

Cloneable интерфейс не содержит" public t clone (); " метод, потому что он действует больше как атрибут (например. Serializable), который позволяет экземпляру быть клонированным.

нет ничего плохого в этой конструкции, потому что:

Comments

    Ничего не найдено.