Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
NoCloneCheck |
|
| 1.0;1 |
1 | //////////////////////////////////////////////////////////////////////////////// | |
2 | // checkstyle: Checks Java source code for adherence to a set of rules. | |
3 | // Copyright (C) 2001-2014 Oliver Burn | |
4 | // | |
5 | // This library is free software; you can redistribute it and/or | |
6 | // modify it under the terms of the GNU Lesser General Public | |
7 | // License as published by the Free Software Foundation; either | |
8 | // version 2.1 of the License, or (at your option) any later version. | |
9 | // | |
10 | // This library is distributed in the hope that it will be useful, | |
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | // Lesser General Public License for more details. | |
14 | // | |
15 | // You should have received a copy of the GNU Lesser General Public | |
16 | // License along with this library; if not, write to the Free Software | |
17 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 | //////////////////////////////////////////////////////////////////////////////// | |
19 | package com.puppycrawl.tools.checkstyle.checks.coding; | |
20 | ||
21 | /** | |
22 | * <p> | |
23 | * Checks that the clone method is not overridden from the | |
24 | * Object class. | |
25 | * </p> | |
26 | * | |
27 | * <p> | |
28 | * Rationale: The clone method relies on strange/hard to follow rules that | |
29 | * do not work it all situations. Consequently, it is difficult to | |
30 | * override correctly. Below are some of the rules/reasons why the clone | |
31 | * method should be avoided. | |
32 | * | |
33 | * <ul> | |
34 | * <li> | |
35 | * Classes supporting the clone method should implement the Cloneable | |
36 | * interface but the Cloneable interface does not include the clone method. | |
37 | * As a result, it doesn't enforce the method override. | |
38 | * </li> | |
39 | * <li> | |
40 | * The Cloneable interface forces the Object's clone method to work | |
41 | * correctly. Without implementing it, the Object's clone method will | |
42 | * throw a CloneNotSupportedException. | |
43 | * </li> | |
44 | * <li> | |
45 | * Non-final classes must return the object returned from a call to | |
46 | * super.clone(). | |
47 | * </li> | |
48 | * <li> | |
49 | * Final classes can use a constructor to create a clone which is different | |
50 | * from non-final classes. | |
51 | * </li> | |
52 | * <li> | |
53 | * If a super class implements the clone method incorrectly all subclasses | |
54 | * calling super.clone() are doomed to failure. | |
55 | * </li> | |
56 | * <li> | |
57 | * If a class has references to mutable objects then those object | |
58 | * references must be replaced with copies in the clone method | |
59 | * after calling super.clone(). | |
60 | * </li> | |
61 | * <li> | |
62 | * The clone method does not work correctly with final mutable object | |
63 | * references because final references cannot be reassigned. | |
64 | * </li> | |
65 | * <li> | |
66 | * If a super class overrides the clone method then all subclasses must | |
67 | * provide a correct clone implementation. | |
68 | * </li> | |
69 | * </ul> | |
70 | * </p> | |
71 | * | |
72 | * <p> | |
73 | * Two alternatives to the clone method, in some cases, is a copy constructor | |
74 | * or a static factory method to return copies of an object. Both of these | |
75 | * approaches are simpler and do not conflict with final fields. They do not | |
76 | * force the calling client to handle a CloneNotSupportedException. They also | |
77 | * are typed therefore no casting is necessary. Finally, they are more | |
78 | * flexible since they can take interface types rather than concrete classes. | |
79 | * </p> | |
80 | * | |
81 | * <p> | |
82 | * Sometimes a copy constructor or static factory is not an acceptable | |
83 | * alternative to the clone method. The example below highlights the | |
84 | * limitation of a copy constructor (or static factory). Assume | |
85 | * Square is a subclass for Shape. | |
86 | * | |
87 | * <pre> | |
88 | * Shape s1 = new Square(); | |
89 | * System.out.println(s1 instanceof Square); //true | |
90 | * </pre> | |
91 | * | |
92 | * ...assume at this point the code knows nothing of s1 being a Square | |
93 | * that's the beauty of polymorphism but the code wants to copy | |
94 | * the Square which is declared as a Shape, its super type... | |
95 | * | |
96 | * <pre> | |
97 | * Shape s2 = new Shape(s1); //using the copy constructor | |
98 | * System.out.println(s2 instanceof Square); //false | |
99 | * </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 | * </p> | |
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 | * </p> | |
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 | */ | |
129 | public class NoCloneCheck extends AbstractIllegalMethodCheck | |
130 | { | |
131 | /** | |
132 | * Creates an instance. | |
133 | */ | |
134 | public NoCloneCheck() | |
135 | { | |
136 | 1 | super("clone", "avoid.clone.method"); |
137 | 1 | } |
138 | } |