On Fri, Jul 12, 2013 at 4:30 AM, Peter Levart <peter.lev...@gmail.com> wrote: > On 07/12/2013 01:14 AM, Zhong Yu wrote: > > On Thu, Jul 11, 2013 at 4:08 PM, Peter Levart <peter.lev...@gmail.com> > wrote: > > Hi Paul, > > I think the MayHoldCloseableResource extends AutoClosable is correct and > AutoClosable extends MayHoldCloseableResource would be wrong. > > And exactly because of "Liskov": > > MayHoldCloseableResource contract says: "If you know it holds a resource, > call close(), otherwise you need not call close(), but it's not wrong to > call it anyway - you know whether it holds resource by looking at > @HoldsResource annotation" > > AutoClosable contract says: "It holds a resource, you should call close()" > > > Now imagine code that was written for the AutoClosable contract. Would it > work if you pass it an instance of MayHoldCloseableResource? Allways. > > Now imagine generic code that was written for MayHoldCloseableResource > contract and which uses the lookup of @HoldsResource at runtime to decide > > How do you lookup an annotation on an _instance_ at runtime? > > > Hi Zhong (and Roger), > > Well, if @HoldsResource had RUNTIME retention, then by using: > > instance.getClass(), ... clazz.getSuperclass(), getInterfaces(), ... etc. > > > And why > do we even care? Just call close() regardless. > > > I was just trying to illustrate a hypothetical code that works with > MayHoldCloseableResource contract and breaks if AutoCloseable is passed to > it. In case AutoCloseable was a subtype of MayHoldCloseableResource, > considering Liskov substitution principle, it should work: "if S is a > subtype of T, then objects of type T may be replaced with objects of type S > (i.e., objects of type S may be substituted for objects of type T) without > altering any of the desirable properties of that program (correctness, task > performed, etc.)". In reality the decision about calling or not calling the > close() is hard-coded by the programmer, guided by static analysis tools, > IDEs and so on, but that doesn't change the reasoning. > > > > And we can revert the parent/child relation, because the "otherwise > specified" clause is a panacea. > > Could you elaborate that?
A supertype can be very vague on its contract, making it possible that subtypes of vast different behaviors can all be compatible with the super type. Consider this design interface PseudoCloseable /** no need to call close(), * unless otherwise specified, then must call close(). * safe to call close() even if there's no need to call it. void close(); interface AutoCloseable extends PseudoCloseable /** must call close * unless otherwise specified, then no need to call close() * safe to call close() even if there's no need to call it. void close(); class ByteArrayInputStream extends Closeable /** has no effect void close(); It works as well/badly as the official design. Zhong Yu > > > Regards, Peter > > > > Zhong Yu > > > whether to call close() or not. Would it work if you pass it an instance of > AutoClosable? Never (since AutoClosable says nothing about any annotation). > > So I argue that MayHoldCloseableResource should be a subtype of AutoClosable > and not the other way around. > > (I have not said anything about whether the MayHoldCloseableResource is > actually needed or not.) > > > Regards, Peter > > > > On 07/11/2013 10:22 PM, Paul Benedict wrote: > > Paul S.'s said the "negative" of using AutoCloseable is "it is no longer > clear whether a stream should be closed or not" (6/20). That's true > because > the semantics of AutoCloseable indicates you have a resource that requires > closing. > > However, the choice to make MayHoldCloseableResource a sub-interface of > AutoClosable should be resisted. It's an inverted design. The Liskov > *substitution > principle *says that sub-interfaces can't loosen the contracts of their > superinterface. If anything, AutoCloseable should be subclass of this new > interface, which MIGHT hold a resource that requires closing. The current > choice is just plainly backwards. > > For the above reason stated, and for the fact the interface adds no new > functionality, it's superfluous. If the interface relationship can't be > inverted, then chuck it -- it does nothing anyway. At the least, keep the > annotation. > > Paul > > > On Thu, Jul 11, 2013 at 3:01 PM, Henry Jen <henry....@oracle.com> wrote: > > On 07/11/2013 01:13 AM, Florian Weimer wrote: > > On 07/10/2013 11:30 PM, Henry Jen wrote: > > A new interface, java.util.MayHoldCloseableResource, indicates an > implementation may or may not hold a resource need to be closed. > > Why doesn't close() throw Exception? > > Because there is really much a developer can do on that situation. The > API simply make it not throw a *checked* exception. > > See EG discussion on this topic, > > > > http://mail.openjdk.java.net/pipermail/lambda-libs-spec-experts/2013-June/002081.html > > Annotation {@link HoldsResource} may be used to guide users/static > analysis tools that a MHCR instance that definitely hold a Closeable > resource. > > All this looks a bit odd to me. I suppose the idea is that you don't > want to give up the last reference to a closeable resource without > calling close()—and not leak references which out-live the call to > close(). This is definitely not a property of the type of the resource, > so I don't see why the MayHoldCloseableResource interface is needed (or > can confer relevant information). The HoldsResource annotation could be > useful, but based on the current documentation, it's not clear if it is > actually intended to express the data flow property. > > I would suggest you look at EG discussion on this topic. The MHCR is > different from AutoCloseable on the chances of holding critical > resources. > > Perhaps that suggests the javadoc is not clear enough, I would like to > know what is important and missing. > > Cheers, > Henry > > > >