I'm writing a class in which I have to override the clone() method with the infamous "super.clone() strategy" (it's not my choice).
My code looks like this:
#Override
public myInterface clone()
{
myClass x;
try
{
x = (myClass) super.clone();
x.row = this.row;
x.col = this.col;
x.color = this.color;
//color is a final variable, here's the error
}
catch(Exception e)
{
//not doing anything but there has to be the catch block
//because of Cloneable issues
}
return x;
}
Everything would be fine, except that I can't initialize color without using a constructor, being it a final variable... is there some way to both use super.clone() AND copying final variables?
Since the call to super.clone(); will already create a (shallow) copy of all the fields, final or not, your full method will become:
#Override
public MyInterface clone() throws CloneNotSupportedException {
return (MyInterface)super.clone();
}
This requires that the superclass also implements clone() properly (to ensure that the super.clone() eventually reaches the Object class. All the fields will be copied properly (including final ones), and if you don't require deep clones or any other special functionality, you can use this and then promise that you'll never try to implement clone() again (one of the reasons being that it's not easy to implement it correctly, as evident from this question).
Under the assumption that you don't have another choice you can use Reflection. The following code shows how this forks for the field color.
You need some try-catch around it.
Field f = getClass().getDeclaredField("color");
f.setAccessible(true);
f.set(x, this.color)
One thing to keep being mindful of, when mixing clone and final fields, especially the one with initializers, is that (as one of the comments rightfully says), the values are copied from the original, no matter whether that field is final or not, and initializer be damned.
So if a final field has a dynamic initializer, it's actually not executed. Which, IMHO, is breaking a serious expectation that if I have a final instance field in a class, every new instance of this class is going to initialize the field to whatever value the initializer says it should be.
Here is an example where this can be a (insert your level of seriousness) problem:
import lombok.SneakyThrows;
import java.util.HashMap;
import java.util.Map;
public class App {
public static void main(String[] a) {
Cloned c1 = new Cloned();
c1.d.put("x", "x");
Cloned c2 = c1.clone();
System.out.println("c2.x="+c2.d.get("x"));
c1.d.clear();
System.out.println("c2.x="+c2.d.get("x"));
}
static class Cloned implements Cloneable {
public final Map<String, String> d = new HashMap<>();
#Override
#SneakyThrows
public Cloned clone() {
return (Cloned) super.clone();
}
}
}
Output:
c2.x=x
c2.x=null
Related
I have an inner helper class, and I would like to add each new instance of it to a map in the containing class, like this:
public class SomeService {
private final Map<Integer, ServiceTask> pendingTasksByKey;
private class ServiceTask {
private ServiceTask(int key) {
// initialization...
pendingTasksByKey.put(key, this);
}
}
// the rest of the code follows
}
When I do it, NetBeans complains about using this in the constructor. OK, I get it, it's a dangerous practice in the general case because someone could extend my class and then I would be leaking this referring to an incompletely initialized object. I didn't want to turn off this warning, so I thought that I could make the class final. This way no one would be able to extend my class, and therefore it should be pretty safe to use this, as the initialization is complete as this point. But NetBeans still shows the warning even if I mark the inner class as final.
Am I right or is there something I missed? Is it just NetBeans being too picky? Besides possible multi-threading memory model issues I can't think of any dangers of such this usage.
It's a Netbeans-specific warning. It is a reminder that the object is not yet constructed so it could be a problem. If you aren't doing anything where that will be a problem then you can ignore it. For example look at this code:
class A {
public Object obj;
public A() {
B b = new B();
b.addMe(this);
obj = new Object();
}
}
class B {
ArrayList<A> list = new ArrayList<A>(0);
public void addMe(A a) {
list.add(a);
System.out.println(a.obj.toString());
}
}
This code has a problem and I should not ignore the "leaking this in constructor" warning.
Leaking this in constructor warning has a discussion of this Netbeans warning.
If pendingTasksByKey has a corresponding remove somewhere during the life cycle of these classes I'd say you are right, Netbeans is being picky.
I want to avoid the constructor calling during object creation in java (either default constructor or user defined constructor) . Is it possible to avoid constructor calling during object creation???
Thanks in advance......
Simply extract the intialization logic that you want to avoid into another method called init. You can not avoid calling exactly one constructor.
No matter what pattern or strategy you use, at some point your will need to call a constructor if you want to create an object.
Actually, its possible under some circumstances by using classes from the JVM implementation (which do not belong to the JRE API and are implemenation specific).
One example here http://www.javaspecialists.eu/archive/Issue175.html
It should also be possible using sun.misc.Unsafe.allocateInstance() (Java7)
Also, the constructor is apparently bypassed when using the clone()-method to create a copy of an object (and the class doesn't override clone to implement it different from the Object.clone() method).
All of these possibilities come with strings attached and should be used carefully, if at all.
You can mock the constructors of a class. They will still be called, but not executed. For example, the following JUnit+JMockit test does that:
static class CodeUnderTest
{
private final SomeDependency someDep = new SomeDependency(123, "abc");
int doSomething(String s)
{
someDep.doSomethingElse(s);
return someDep.getValue();
}
}
static final class SomeDependency
{
SomeDependency(int i, String s) { throw new RuntimeException("won't run"); }
int getValue() { return -1; }
}
#Test
public void mockEntireClassIncludingItsConstructors()
{
new NonStrictExpectations() {
#Mocked SomeDependency mockDep;
{ mockDep.getValue(); result = 123; }
};
int result = new CodeUnderTest().doSomething("testing");
assertEquals(123, result);
}
Findbugs gives me for public GsmSignalStrength clone() following warning:
Class defines clone() but doesn't implement Cloneable.
Why do I have to implement Cloneable? Is it because of shallow and deep copy? I have to apologize for my bad Java skills, but I'm a Java newbie.
Here is my code:
class GsmSignalStrength
{
static final byte SIGNAL_STRENGTH_UNKNOWN = 99;
static final byte SIGNAL_STRENGTH_1 = 1;
static final byte SIGNAL_STRENGTH_2 = 2;
static final byte SIGNAL_STRENGTH_3 = 3;
static final byte SIGNAL_STRENGTH_4 = 4;
static final byte SIGNAL_STRENGTH_5 = 5;
/* Constructors */
GsmSignalStrength(byte signalStrength)
{
initClassVars(signalStrength);
}
GsmSignalStrength()
{
initClassVars(SIGNAL_STRENGTH_UNKNOWN);
}
GsmSignalStrength(byte[] serializedData, IntClass deserializationIndex)
{
initClassVars(SIGNAL_STRENGTH_UNKNOWN);
setClassProperties(serializedData, deserializationIndex);
}
byte value;
/* Methods */
public void copyTo(GsmSignalStrength destination)
{
destination.value = this.value;
}
public GsmSignalStrength clone()
{
GsmSignalStrength clonedValue = new GsmSignalStrength();
this.copyTo(clonedValue);
return clonedValue;
}
private void initClassVars(byte signalStrength)
{
this.value = signalStrength;
}
}
Cloneable is not needed here.
This is because your implementation of clone() does not actually clone the object. In Java, cloning specifically means using Object.clone(), which does JVM magic to copy the object. Although your code does something sort of equivalent to cloning (and better, IMHO - it avoids using magic), it is not true cloning.
However, findbugs doesn't know that, so it's worried that you might be trying to clone a non-Cloneable object.
One solution here might be to rename your method to something else (copy()?), so it doesn't appear to be a clone.
You can read the documentation.
A class implements the Cloneable interface to indicate to the Object.clone() method that it is legal for that method to make a field-for-field copy of instances of that class.
Invoking Object's clone method on an instance that does not implement the Cloneable interface results in the exception CloneNotSupportedException being thrown.
However you are not using clone() method in the right way. Look at this wiki page.
if you implement clone as
public GsmSignalStrength clone()
{
try{
GsmSignalStrength clonedValue = (GsmSignalStrength )super.clone();
this.copyTo(clonedValue);
return clonedValue;
}catch(CloneNotSupportedException e){thrown new RunTimeException(e);}
}
(which if you are ever going to subclass GsmSignalStrength you are going to need to be according to the documention of Object.clone())
the super.clone call will throw a CloneNotSupportedException
I was asking this question about controlling a thread that was reading from a blocking queue. Although it wasn't the solution I chose to go with, several people suggested that a special "poison pill" or "sentinel" value be added to the queue to shut it down like so:
public class MyThread extends Thread{
private static final Foo STOP = new Foo();
private BlockingQueue<Foo> blockingQueue = new LinkedBlockingQueue<Foo>();
public void run(){
try{
Foo f = blockingQueue.take();
while(f != STOP){
doSomethingWith(f);
f = blockingQueue.take();
}
}
catch(InterruptedException e){
}
}
public void addToQueue(Foo f) throws InterruptedException{
blockingQueue.put(f);
}
public void stop() throws InterruptedException{
blockingQueue.put(STOP);
}
}
While I like this approach, I decided not to use it because I wasn't sure what value to use for the STOP field. In some situations it's obvious - for instance, if you know you're inserting positive integers, negative numbers could be used as control values - but Foo is a fairly complex class. It's immutable and hence has a constructor that takes several arguments. To add a no-argument constructor would mean leaving several fields uninitialised or null, which would cause methods to break if they were used elsewhere - Foo is not just used with MyThread. Similarly, putting dummy values into the main constructor would just pass this problem on as several of the fields and constructor parameters are themselves significant objects.
Am I simply programming over-defensively? Should I worry about adding no-argument constructors to a class, even if there are no setters to make the object usable (just assume other programmers will be sensible enough to not use that constructor)? Is the design of Foo broken if it can't have a no-argument constructor or at least a non-value - would it be better to put if(someField == null){throw new RuntimeException();} checks in all methods?
I don't really see what the advantage of this design is versus a simple boolean variable to indicate the loop should stop.
But if you really want to go with this design, I would suggest making a private no-arg constructor, and making a static STOP Foo. Like this.
public class Foo {
public static final Foo STOP = new Foo();
... fields
private Foo(){}
public Foo(...){
...
}
...
}
public class MyThread extends Thread{
private static final Foo STOP = new Foo();
private BlockingQueue<Foo> blockingQueue = new LinkedBlockingQueue<Foo>();
public void run(){
try{
Foo f = blockingQueue.take();
while(f != STOP){
doSomethingWith(f);
f = blockingQueue.take();
}
}
catch(InterruptedException e){
}
}
public void addToQueue(Foo f) throws InterruptedException{
blockingQueue.put(f);
}
public void stop() throws InterruptedException{
blockingQueue.put(Foo.STOP);
}
}
This has the advantage that you're still not exposing an invalid constructor.
The disadvantage is that the Foo class knows that in some cases it's used as a 'poison pill', which might not be what it's for. Another disadvantage is that The STOP object might be inconsistent. You could make an anonymous subclass from it do disable the methods with UnsupportedOperationException or something.
I think you're right about not using empty constructors. If Foo is such an complex class, it doesn't seem logical to use a complete object for that.
If adding a null is possible. That seems a nice way to go.
Another way could also be to implement an interface. IBlockableQueueObject? This could be implemented by the foo object and by the STOP sign. Only thing is that you have to cast the interface back to the Foo if it is not a STOP.
another option would be to wrap Foo in a generic wrapper such as this:
public class Wrapped<T> {
private final T value;
public Wrapped(T value) {
this.value = value;
}
public T get() { return value; }
}
which you can then use to pass a null value as a poison pill to a BlockingQueue<Wrapped<Foo>>.
You should worry about having no-argument constructors that don't result in usable instances.
The design of Foo sounds fine - I would generally assume that I'm not allowed to pass in null into a constructor unless the documentation specifically allows me to. Especially with an immutable class.
Is it possible to get the class type from inside the static initialization block?
This is a simplified version of what I currently have::
class Person extends SuperClass {
String firstName;
static{
// This function is on the "SuperClass":
// I'd for this function to be able to get "Person.class" without me
// having to explicitly type it in but "this.class" does not work in
// a static context.
doSomeReflectionStuff(Person.class); // IN "SuperClass"
}
}
This is closer to what I am doing, which is to initialize a data structure that holds information about the object and its annotations, etc... Perhaps I am using the wrong pattern?
public abstract SuperClass{
static void doSomeReflectionStuff( Class<?> classType, List<FieldData> fieldDataList ){
Field[] fields = classType.getDeclaredFields();
for( Field field : fields ){
// Initialize fieldDataList
}
}
}
public abstract class Person {
#SomeAnnotation
String firstName;
// Holds information on each of the fields, I used a Map<String, FieldData>
// in my actual implementation to map strings to the field information, but that
// seemed a little wordy for this example
static List<FieldData> fieldDataList = new List<FieldData>();
static{
// Again, it seems dangerous to have to type in the "Person.class"
// (or Address.class, PhoneNumber.class, etc...) every time.
// Ideally, I'd liken to eliminate all this code from the Sub class
// since now I have to copy and paste it into each Sub class.
doSomeReflectionStuff(Person.class, fieldDataList);
}
}
Edit
I picked the accepted answer based on what applied best to my problem, however it seems to me that all three of the current answers have their merits.
No, it's not possible without grabbing the stacktrace (which is imo nastier than your initial approach and for which I would in any way prefer Thread#getStackTrace() above new Exception()).
Rather do that job in a non-static initializer (or the default constructor) of the abstract class where you check the initialized status.
public abstract class SuperClass {
{
if (!isInitialized(getClass())) {
initialize(getClass());
}
}
}
The called methods in turn can be safely static.
yes, I use this often to initialize a static Log variable :
e.g. :
public class Project implements Serializable, Cloneable, Comparable<Project> {
private static final Logger LOG = LoggerFactory.getLogger(Project.class);
...
To get a class at runtime, you could do something along the lines of
public class Test {
public static void main(String[] args) {
try{
throw new Exception();
}
catch(Exception e){
StackTraceElement[] sTrace = e.getStackTrace();
// sTrace[0] will be always there
String className = sTrace[0].getClassName();
System.out.println(className);
}
}
}
Not pretty but will do the job (ripped from http://www.artima.com/forums/flat.jsp?forum=1&thread=155230).
This means you still make a call from the subclass (so is in the stack trace), but you don't need to include the XXX.class as an argument.