Клонирование целого числа - PullRequest
8 голосов
/ 28 апреля 2011

Я пытаюсь клонировать объект класса Integer, который реализует клонируемый интерфейс.

Integer a = new Integer(4);  
Integer b = a.clone();

Я знаю, что для этого есть обходные пути, но я должен реализовать это следующим образом. почему я получаю эту ошибку = clone() имеет защищенный доступ в java.lang.Object

С чего бы это говорить? Разве метод клонирования не является публичным абстрактным методом клонируемого интерфейса, что он имеет отношение к объекту. Заранее спасибо: -)

Ответы [ 7 ]

14 голосов
/ 28 апреля 2011

java.lang.Integer с неизменяемы.Там нет причин, чтобы клонировать один.Если вы пытаетесь потратить впустую память, попробуйте Integer.valueOf(myInteger.intValue()).

9 голосов
/ 28 апреля 2011

Конечно, все методы в Object наследуются.Однако метод clone имеет вид protected, поэтому доступен только из подклассов.

Защищенный модификатор указывает, что доступ к элементу возможен только внутри его собственногоpackage (как с package-private) и, кроме того, подклассом своего класса в другом пакете.

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

2 голосов
/ 28 апреля 2011

Как указывают Amit и aioobe, Integer является неизменным, поэтому нет необходимости его клонировать.

Но чтобы ответить на ваш вопрос. Метод clone () не является частью интерфейса clonable, см .: http://download.oracle.com/javase/6/docs/api/java/lang/Cloneable.html, как говорит aioobe.

Метод clone объявлен как защищенный в Object, и вы должны перезаписать его открытым методом, чтобы использовать его. Смотри http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#clone()

Короче говоря, причина этого заключается в том, что для клонирования объекта может понадобиться или не потребоваться выполнение «глубокого клонирования», например. поля клонов и их подэлементы. Или может не иметь смысла клонировать объект, как в случае с Integer (потому что он неизменен)

2 голосов
/ 28 апреля 2011

Ошибка возникает потому, что clone метод java.lang.Object не виден публично.

1 голос
/ 28 апреля 2011

Прежде всего, получение копии с помощью клонирования, в которой я нуждался, когда вы не хотите, чтобы другие изменили вашу копию. Теперь Integer - это класс-оболочка, такой как String и Double, которые Immutable . Это означает, что вы не можете изменить его внутренности. Так что, пока у вас есть исходная ссылка, ваш объект не поврежден.

говорят

Integer a = new Integer(4); // a referencing to this newly Created Integer
    b = a;  // b is referencing to..
    b = new Integer(8) // b no longer references to 4. 
                      //We changed the reference not the internals of it which is impossible.
0 голосов
/ 22 сентября 2016

Да, поскольку метод clone () защищен , он может быть только унаследован, но его нельзя вызвать для объекта другого класса. Каждый класс наследует Object, поэтому вы можете просто вызвать clone ().

Но в (по умолчанию / родном) методе clone () у вас есть if () {}, в котором, если ваш класс не реализует Cloneable, он выдаст исключение CloneNotSupportedException. Я сказал нативный, потому что метод clone () является нативным, когда вы его вызываете, вызвал другой метод, написанный в C ++.

Вот небольшая часть кода, которая вызывается при вызове clone ().

if (!klass->is_cloneable()) {
    ResourceMark rm(THREAD);
    THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name());
  }

спасибо Можно ли найти источник для нативного метода Java?

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

public class Main{
    public static void main(String[] args) throws CloneNotSupportedException {
        A a = new A();
        Object o = new Object();
        Method method = null;
        try {
            method = o.getClass().getDeclaredMethod("clone");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        method.setAccessible(true);
        try {
            System.out.println(method.invoke(a));
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

class A implements Cloneable {
}

и method.invoke(a) instanceof A оценивается как истинное

без реализации Cloneable вы получите

Caused by: java.lang.CloneNotSupportedException: defaultPackage.A
    at java.lang.Object.clone(Native Method)

И поскольку Integer не реализует Cloneable, метод clone () будет генерировать исключение java.lang.CloneNotSupportedException.

0 голосов
/ 28 апреля 2011

В это может быть трудно поверить, но ваша ошибка верна: clone () имеет защищенный доступ в java.lang.Object

...