3

(This is a follow-up to my previous question.)

I have an interface called Copyable, which has a single function

Copyable getObjectCopy();

This is used by many other classes. Because this function always returns a Copyable, it results in unchecked casts. Example:

@SuppressWarnings("unchecked")  //Copy of itself is the same type.
ValidateValue<L> vvo = (ValidateValue<O>)this_toCopy.getValidator().getObjectCopy();
vvBlkA = vvo;

My question relates to Josh Bloch`s recommendation (in Effective Java, 2nd ed., item 24):

Every time you use an @SuppressWarnings("unchecked") annotation, add a comment saying why it's safe to do so.

His example is

// This cast is correct because the array we're creating
// is of the same type as the one passed in, which is T[].
@SuppressWarnings("unchecked")
T[] result = (T[]) Arrays.copyOf(elements, size, a.getClass());
return  result;

(see the bottom of page 9 / 117: http://www.infoq.com/resource/articles/bloch-effective-java-2e/en/resources/Bloch_Ch05.pdf)

I like this idea, and I want to it with getObjectCopy()

@SuppressWarnings("unchecked")  //Copy of itself is the same type.
ValidateValue<L> vvo = (ValidateValue<O>)this_toCopy.getValidator().getObjectCopy();
vvBlkA = vvo;

My comment seems lame, but I can't think of anything better. And that's my question: Why is this unchecked-cast justifiable? What's a meaningful comment that would actually help future developers, that means something more than, effectively, "just trust me"?

Community
  • 1
  • 1
aliteralmind
  • 19,847
  • 17
  • 77
  • 108
  • I'm finding your question really hard to follow. It would have been better if you'd posted the code, rather than just describing it. Are you actually declaring `TextLineValidator getObjectCopy()` in your `TextLineValidator` interface or not? – Dawood ibn Kareem Jan 29 '14 at 03:44
  • Darn. I added an expanded version at the bottom. `TextLineValidator` *used* to have `TextLineValidator getObjectCopy()`, but after wrestling with my previous question, it's now `Copyable getObjectCopy()` everywhere. – aliteralmind Jan 29 '14 at 03:50
  • Well, there's your problem. If `LineGetter` says that `getObjectCopy()` returns `LineGetter`, then `TextLineValidator` can't say that it returns `Copyable`. Otherwise, you might have a `TextLineValidator` that doesn't obey the contract of `LineGetter`. – Dawood ibn Kareem Jan 29 '14 at 03:53
  • Huh. That actually gives me a deeper understanding of why the solution to that question--that `getObjectCopy()` must always return a `Copyable`--is the right one. All the background is overshadowing my actual question... – aliteralmind Jan 29 '14 at 03:56
  • Can't TextLineValidator.getObjectCopy() be declared to return TextLineValidator via co-variance and avoid the whole issue? – user207421 Jan 29 '14 at 04:27
  • If I'm understanding you, that conflicts with the solution to my previous question, http://stackoverflow.com/q/21388479/2736496 , which this is a follow-up to. Using `TextLineValidator getObjectCopy()` results in the following compilation error, because the hierarchy is a diamond: `types LineGettable and ValidateValue are incompatible; both define getObjectCopy(), but with unrelated return types` – aliteralmind Jan 29 '14 at 04:33
  • I don't see how you can get that error from this code. Both those methods are declared to return Copyable in what you've posted here. – user207421 Jan 29 '14 at 04:47
  • These `getObjectCopy()` functions now absolutely return `Copyable`. Every one of them. They *used* to return their individual types (co-variance), as discussed in my previous question (see the link at the top of the post). Having them all return `Copyable` is what I need, because it avoids exactly those compilation problems. This question relates to the *consequence* of that solution: Namely, how do I justify the unchecked-cast warnings in my internal comments. Boy is this all confused now. – aliteralmind Jan 29 '14 at 04:54
  • 1
    If they all return Copyable you should be able to do what I recommended above, and not get the error you got when they didn't. But I think I would also investigate defining Copyable as Copyable>, like Comparable, and have getObjectCopy() return T. – user207421 Jan 29 '14 at 04:57
  • (OBLITERATED the background in hopes of making it less confusing.) That is an interesting suggestion, EJP. Have not used generics in that way before. – aliteralmind Jan 29 '14 at 05:13

1 Answers1

3

We are in Java 5+ world now! User Generics.

You can change the signature of Copyable to something like:

interface Copyable<T extends Copyable> {
    T getObjectCopy();
}

Now your ValidateValue<L> value would be something like:

puvlic class ValidateValue<L> implements Copyable<ValidateValue<L>> {
    ...
}

and everyone (including the compiler) would be happy!

Amir Pashazadeh
  • 7,170
  • 3
  • 39
  • 69