001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2014 Oliver Burn 004// 005// This library is free software; you can redistribute it and/or 006// modify it under the terms of the GNU Lesser General Public 007// License as published by the Free Software Foundation; either 008// version 2.1 of the License, or (at your option) any later version. 009// 010// This library is distributed in the hope that it will be useful, 011// but WITHOUT ANY WARRANTY; without even the implied warranty of 012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013// Lesser General Public License for more details. 014// 015// You should have received a copy of the GNU Lesser General Public 016// License along with this library; if not, write to the Free Software 017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 018//////////////////////////////////////////////////////////////////////////////// 019package com.puppycrawl.tools.checkstyle.checks.coding; 020 021/** 022 * <p> 023 * Checks that the clone method is not overridden from the 024 * Object class. 025 * </p> 026 * 027 * <p> 028 * Rationale: The clone method relies on strange/hard to follow rules that 029 * do not work it all situations. Consequently, it is difficult to 030 * override correctly. Below are some of the rules/reasons why the clone 031 * method should be avoided. 032 * 033 * <ul> 034 * <li> 035 * Classes supporting the clone method should implement the Cloneable 036 * interface but the Cloneable interface does not include the clone method. 037 * As a result, it doesn't enforce the method override. 038 * </li> 039 * <li> 040 * The Cloneable interface forces the Object's clone method to work 041 * correctly. Without implementing it, the Object's clone method will 042 * throw a CloneNotSupportedException. 043 * </li> 044 * <li> 045 * Non-final classes must return the object returned from a call to 046 * super.clone(). 047 * </li> 048 * <li> 049 * Final classes can use a constructor to create a clone which is different 050 * from non-final classes. 051 * </li> 052 * <li> 053 * If a super class implements the clone method incorrectly all subclasses 054 * calling super.clone() are doomed to failure. 055 * </li> 056 * <li> 057 * If a class has references to mutable objects then those object 058 * references must be replaced with copies in the clone method 059 * after calling super.clone(). 060 * </li> 061 * <li> 062 * The clone method does not work correctly with final mutable object 063 * references because final references cannot be reassigned. 064 * </li> 065 * <li> 066 * If a super class overrides the clone method then all subclasses must 067 * provide a correct clone implementation. 068 * </li> 069 * </ul> 070 * 071 * 072 * <p> 073 * Two alternatives to the clone method, in some cases, is a copy constructor 074 * or a static factory method to return copies of an object. Both of these 075 * approaches are simpler and do not conflict with final fields. They do not 076 * force the calling client to handle a CloneNotSupportedException. They also 077 * are typed therefore no casting is necessary. Finally, they are more 078 * flexible since they can take interface types rather than concrete classes. 079 * 080 * 081 * <p> 082 * Sometimes a copy constructor or static factory is not an acceptable 083 * alternative to the clone method. The example below highlights the 084 * limitation of a copy constructor (or static factory). Assume 085 * Square is a subclass for Shape. 086 * 087 * <pre> 088 * Shape s1 = new Square(); 089 * System.out.println(s1 instanceof Square); //true 090 * </pre> 091 * 092 * ...assume at this point the code knows nothing of s1 being a Square 093 * that's the beauty of polymorphism but the code wants to copy 094 * the Square which is declared as a Shape, its super type... 095 * 096 * <pre> 097 * Shape s2 = new Shape(s1); //using the copy constructor 098 * System.out.println(s2 instanceof Square); //false 099 * </pre> 100 * 101 * The working solution (without knowing about all subclasses and doing many 102 * casts) is to do the following (assuming correct clone implementation). 103 * 104 * <pre> 105 * Shape s2 = s1.clone(); 106 * System.out.println(s2 instanceof Square); //true 107 * </pre> 108 * 109 * Just keep in mind if this type of polymorphic cloning is required 110 * then a properly implemented clone method may be the best choice. 111 * 112 * 113 * <p> 114 * Much of this information was taken from Effective Java: 115 * Programming Language Guide First Edition by Joshua Bloch 116 * pages 45-52. Give Bloch credit for writing an excellent book. 117 * </p> 118 * 119 * <p> 120 * This check is almost exactly the same as the {@link NoFinalizerCheck} 121 * 122 * 123 * @author Travis Schneeberger 124 * @version 1.0 125 * @see java.lang.Object#clone() 126 * @see java.lang.Cloneable 127 * @see java.lang.CloneNotSupportedException 128 */ 129public class NoCloneCheck extends AbstractIllegalMethodCheck 130{ 131 /** 132 * Creates an instance. 133 */ 134 public NoCloneCheck() 135 { 136 super("clone", "avoid.clone.method"); 137 } 138}