Java Forum / First Aid / June 2005
the purpose of marker interface in java
jrefactors@hotmail.com - 13 Jun 2005 19:24 GMT I know what is marker interface - An interface with no methods. Example: Serializable, Remote, Cloneable.
But I don't know the purpose of using marker interface, and when is the good practice for that.
Please advise. thanks!!
Matt Humphrey - 13 Jun 2005 20:17 GMT > I know what is marker interface - An interface with no methods. > Example: Serializable, Remote, Cloneable. [quoted text clipped - 3 lines] > > Please advise. thanks!! Sometimes different kinds of objects are differentiated without having any different methods or properties. Marker interfaces allow a program to determine if an object has some characteristic and behave accordingly. Consider the following example: I have a system that has a dozen different kinds of objects that are manipulated by the user: Person, Vehicle, RealEstate, Property, Spouse, Dependent, etc. There is no meaningful inheritance hierarchy that contains them all. Perhaps some of these represent and so have to be managed by special privacy rules. This can be done by making up and marking them with a "Privacy" interface tag. When the UI manipulates objects, it treats those that are "Privacy" instances differently. Similarly, some could also be marked as for other purposes. Often the marking has more to do with the programmatic mechanics of the object rather than its semantics and there's a fine line between what constitutes good design for using marker interfaces versus a good design for classes in general.
Cheers, Matt Humphrey matth@ivizNOSPAM.com http://www.iviz.com
Thomas G. Marshall - 13 Jun 2005 22:50 GMT Matt Humphrey coughed up:
>> I know what is marker interface - An interface with no methods. >> Example: Serializable, Remote, Cloneable. [quoted text clipped - 12 lines] > etc. There is no meaningful inheritance hierarchy that contains them > all. Yes.
However, it should be noted that because an empty interface is by definition establishing no behavior (other than the obvious "no behavior" behavior
:) ), downcasting is often required to actually accomplish something. Example:
public interface Pocketable {}
public class Apple {...} implements Pocketable public class Bug {...} implements Pocketable, Gross public class CarKeys{...} implements Pocketable
Pocketable[] inPocket = {new Apple(), new Bug(), new CarKeys()};
for (int i = 0; i<inPocket.length; i++) if (inPocket[i] instanceof Bug) ((Bug)inPocket[i]).pullLegsOff(3); // required downcast
For simply collecting the objects together however, it is very useful.
...[rip]...
 Signature Puzzle: You are given a deck of cards all face down except for 10 cards mixed in which are face up. If you are in a pitch black room, how do you divide the deck into two piles (may be uneven) that each contain the same number of face-up cards? Answer (rot13): Sebz naljurer va gur qrpx, qrny bhg gra pneqf naq syvc gurz bire.
Matt Humphrey - 14 Jun 2005 15:24 GMT > Matt Humphrey coughed up: > >> I know what is marker interface - An interface with no methods. [quoted text clipped - 33 lines] > if (inPocket[i] instanceof Bug) > ((Bug)inPocket[i]).pullLegsOff(3); // required downcast I'm not convinced. Your downcast is required because you want to treat the object as a Bug, not because it's Pocketable. The marker interface is really only used to distinguish between those objects that have the marker and those that don't. In your example, knowing that all the objects are Pocketable isn't meaningful--they might as well have all been Object. Some other part of the program needs to change its behavior based on whether or not the object has the marker.
> For simply collecting the objects together however, it is very useful. That's pretty much it's only purpose.
Cheers, Matt Humphrey matth@ivizNOSPAM.com http://www.iviz.com/
Thomas G. Marshall - 14 Jun 2005 19:22 GMT Matt Humphrey coughed up:
>> Matt Humphrey coughed up: >>>> I know what is marker interface - An interface with no methods. [quoted text clipped - 37 lines] > > I'm not convinced. What do you think I'm trying to convince you of?
> Your downcast is required because you want to > treat the object as a Bug, not because it's Pocketable. Correct. I have a bunch of things in my pocket, and I wish to do something to only the bugs.
> The marker > interface is really only used to distinguish between those objects > that have the marker and those that don't. Sure. As in my example.
> In your example, knowing > that all the objects are Pocketable isn't meaningful--they might as > well have all been Object. *NO* !
The array is an array of only things that can be in a pocket. Had I made it an array of Object, it would have had no type safety whatsoever. One of the things in my pocket might *well* have been a car or house at a later point in time, added by a very tired engineer!!!
> Some other part of the program needs to > change its behavior based on whether or not the object has the marker. That's embodied entirely in the loop. It's a loop entirely of the array, which is entirely /only/ of things that /can/ be and are in my pocket.
>> For simply collecting the objects together however, it is very >> useful. > That's pretty much it's only purpose. And once you do that, you then do /what/ with it?
Tell me how you would build an array of things that are only pocketable, when you cannot use a common superclass?
Realize that the purpose of my post was to supply what was some of the baggage was about marker interfaces. That you need to do a downcast, while not strictly a no-no even for the OO purists in comp.object, is not ideal.
 Signature "It's easier to be terrified by an enemy you admire." -Thufir Hawat, Mentat and Master of Assassins to House Atreides
Thomas G. Marshall - 14 Jun 2005 19:23 GMT Thomas G. Marshall coughed up:
> Matt Humphrey coughed up: >>> Matt Humphrey coughed up: [quoted text clipped - 86 lines] > while not strictly a no-no even for the OO purists in comp.object, is > not ideal. The point of "downcast" in this regard is of course added to the good or bad issue of RTTI, as in my example.
 Signature "It's easier to be terrified by an enemy you admire." -Thufir Hawat, Mentat and Master of Assassins to House Atreides
Matt Humphrey - 14 Jun 2005 23:26 GMT > Thomas G. Marshall coughed up: > > Matt Humphrey coughed up: [quoted text clipped - 41 lines] > > > > What do you think I'm trying to convince you of? That marker interfaces often require downcasting in order to accomplish something. Marker interfaces are only identify some objects out of a larger collection. I believe that what you do with those objects (and any downcasting required) is a separate issue. The typical marker interfaces for Cloneable, etc don't require any downcasting at all. If you're identifying objects in order to do something special (not in the superclass interface) with them, it seems a regular interface would be more appropriate. I see a more typical marker interface example as:
UserItem [] userItems = getMyItems (userId); for (int i = 0; i < userItems.length; ++i) { if (userItems[i] instanceof Pocketable) { userItem[i].discard (); } }
Discarding is a general operation on UserItem. But I'm only discarding Pocketable items.
> >> Your downcast is required because you want to > >> treat the object as a Bug, not because it's Pocketable. > > > > Correct. I have a bunch of things in my pocket, and I wish to do > > something to only the bugs. Which really has nothing to do with marker interfaces. If you wanted to do something only to the Bugs, why not just select on Bug to begin with?
> >> The marker > >> interface is really only used to distinguish between those objects [quoted text clipped - 13 lines] > > car or house at a later point in time, added by a very tired > > engineer!!! Although that's certainly true, I don't think I'll start marking all the objects in my systems as "MyAppObject" just to make sure no one slips in objects from some other application :-).
> >> Some other part of the program needs to > >> change its behavior based on whether or not the object has the [quoted text clipped - 12 lines] > > Tell me how you would build an array of things that are only > > pocketable, when you cannot use a common superclass? The marker is useful for building the collection, not for using it. If the point is to collect a subset of objects and do something special and unique to them that is not otherwise defined by a superclass, you probably should be using a real interface. Similarly, if the objects are all subclasses of some common superclass (whether it's Object, etc), it is still useful to distinguish some object classes from others (e.g. Clonable, Mutable, Externalizable, etc) even though the behavior will still be defined through the superclass.
> > Realize that the purpose of my post was to supply what was some of the > > baggage was about marker interfaces. That you need to do a downcast, [quoted text clipped - 3 lines] > The point of "downcast" in this regard is of course added to the good or bad > issue of RTTI, as in my example. I think your point is well made that marker interfaces don't help with determining behavior. I just happen to see that as an issue more to do with defining and handling subclass behavior than with marker interfaces.
Cheers, Matt Humphrey matth@ivizNOSPAM.com http://www.iviz.com/
Thomas G. Marshall - 15 Jun 2005 00:36 GMT Matt Humphrey coughed up:
>> Thomas G. Marshall coughed up: >>> Matt Humphrey coughed up: [quoted text clipped - 47 lines] > objects out of a larger collection. I believe that what you do with > those objects (and any downcasting required) is a separate issue. But you're not disagreeing then. To /do/ anything with that object often requires downcasting to some type that /has/ the behavior you need.
> The typical marker interfaces for Cloneable, etc don't require any > downcasting at all. Wrong! First of all, clone() lives in Object, but does not work unless you use the marker interface, but that doesn't bend the rules any. If you decide to make an array of Cloneable items:
Cloneable[] cloneableItems = {...};
then you *have* to downcast if you wish to access things (behaviors) that don't exist in Object.
We should stay clear of discussing interface here. Cloneable is a particularly weird built-in case, which has nothing to do with any marker interfaces a user might concoct on his own, the reasons for doing so being the topic of this discussion.
> If you're identifying objects in order to do > something special (not in the superclass interface) with them, it [quoted text clipped - 10 lines] > Discarding is a general operation on UserItem. But I'm only > discarding Pocketable items. {Sigh}. These Pocketable items----how do you define them? I have given you an example of an apple, a bug, and a set of car keys, each their own class. If they were already inheriting from some other types (something that is part of their individual hierarchies) then how do I write code to:
1. model the collection of items in my pocket. 2. write code to pull the legs off of all the bugs in my pocket.
You *cannot*, unless you provide the code example I gave.
>>>> Your downcast is required because you want to >>>> treat the object as a Bug, not because it's Pocketable. [quoted text clipped - 5 lines] > to do something only to the Bugs, why not just select on Bug to begin > with? What are you talking about? And collect them in my pocket how? The identifier "inPocket" is an array of things to hold in my pocket. You have 3 choices here:
1. Make the array of some common superclass that holds all the behavior I need. 2. Make the array of some common superclass that is just "high enough" to hold them all. You mentioned Object. 3. Make the array of some common interface.
I cannot do 1, because as I said, the superclasses are already established as something else. I can do 2, but then I don't have any type safety, and I *STILL* have to downcast anyway (!) to operate on the bugs in my pocket. The option #3 is the clear alternative.
...[rip]...
>>>> In your example, knowing >>>> that all the objects are Pocketable isn't meaningful--they might as [quoted text clipped - 11 lines] > the objects in my systems as "MyAppObject" just to make sure no one > slips in objects from some other application :-). (?) Is there a point here?
Let's look at it this way, perhaps you'll understand this better:
You're tasked with modeling a person. The person is associated with 0..1 pairs of pants. (he could be naked). The Pants have a pocket. The pocket holds anything Pocketable, any number of disparate objects in the system. You need to operate on items that are only *in the pocket*, and in this case, you need to pull the legs off of any bugs in your pocket.
>>>> Some other part of the program needs to >>>> change its behavior based on whether or not the object has the [quoted text clipped - 17 lines] > special and unique to them that is not otherwise defined by a > superclass, you probably should be using a real interface. With what behavior in that interface? Write the code to do what my code did: Maintain a pocket of items that are only meant for a pocket. And pull the legs off of all the bugs in the pocket.
...[rip]...
> I think your point is well made that marker interfaces don't help with > determining behavior. I just happen to see that as an issue more to > do with defining and handling subclass behavior than with marker > interfaces. These are disparate objects, only knit together in that they are pocketable. Again, I'll repeat, "when you cannot use a common superclass".
 Signature Whyowhydidn'tsunmakejavarequireanuppercaselettertostartclassnames....
Matt Humphrey - 24 Jun 2005 00:17 GMT I had intended to reply sooner, but work is such an distraction.
[snip preamble]
>> The typical marker interfaces for Cloneable, etc don't require any >> downcasting at all. > > Wrong! First of all, clone() lives in Object, but does not work unless > you use the marker interface, but that doesn't bend the rules any. If you > decide to make an array of Cloneable items: I agree Cloneable isn't a good example, but I'm not sure what you mean that clone() doesn't work unless I use the marker interface. Of course the actual class has to be marked Cloneable, but I don't have to downcast an object to Cloneable to use use clone (). I think you mean that I have to downcast the generated object, but that's not a fault of the marker interface--the same is true for ObjectInputStream.
> Cloneable[] cloneableItems = {...}; > [quoted text clipped - 5 lines] > interfaces a user might concoct on his own, the reasons for doing so being > the topic of this discussion. I agree--it's not a good example. Dale pointed out the deficiences of the standard marker interfaces.
>> If you're identifying objects in order to do >> something special (not in the superclass interface) with them, it [quoted text clipped - 20 lines] > > You *cannot*, unless you provide the code example I gave. I agree that if the objects have nothing in common you will have to downcast to something they do have in common. That doesn't mean they can't be members of some common interface where particular subclasses are marked with marker interfaces.
>>>>> Your downcast is required because you want to >>>>> treat the object as a Bug, not because it's Pocketable. [quoted text clipped - 18 lines] > I cannot do 1, because as I said, the superclasses are already established > as something else. But there may still be common interfaces that apply, so 1 is possible.
> I can do 2, but then I don't have any type safety, and I *STILL* have to > downcast anyway (!) to operate on the bugs in my pocket. The option #3 is > the clear alternative. > > ...[rip]... [ snip ]
>>>>>> For simply collecting the objects together however, it is very >>>>>> useful. [quoted text clipped - 4 lines] >>>> Tell me how you would build an array of things that are only >>>> pocketable, when you cannot use a common superclass? I don't understand why you discount using a common superclass (interface). Are you presuming that, in theory, the designer of any common interface could encode any marker interface within it (e.g. isPocketable ())? Things may not work out that way in practice and I can use a marker interface and invoke behaviors without downcasting because of the common interface.
>> The marker is useful for building the collection, not for using it. >> If the point is to collect a subset of objects and do something [quoted text clipped - 14 lines] > These are disparate objects, only knit together in that they are > pocketable. Again, I'll repeat, "when you cannot use a common superclass". I definately agree that if you don't have a common superclass, not only will you have to downcast, but being able to select an object that holds a marker interface doesn't do very much good. In the past week I thought about where I had used marker interfaces in the past--only in one project a couple of years ago--and about 2 months down the road it only made sense to put methods on the interface.
Cheers, Matt Humphrey matth@ivizNOSPAM.com http://www.iviz.com/
Thomas G. Marshall - 24 Jun 2005 19:11 GMT Matt Humphrey coughed up:
> "Thomas G. Marshall" > <tgm2tothe10thpower@replacetextwithnumber.hotmail.com> wrote in ...[rip]...
>> {Sigh}. These Pocketable items----how do you define them? I have >> given you an example of an apple, a bug, and a set of car keys, each [quoted text clipped - 9 lines] > can't be members of some common interface where particular subclasses > are marked with marker interfaces. (?) So what? If I am creating an array of a particular type and the only unifying reason for that type is to simply indicate that they are pocketable, then the marker interface I'm talking about should be empty. You *do* *not* *want* to add behavior to something when it is unnecessary.
...[rip]...
> I don't understand why you discount using a common superclass > (interface). Because, as you know, *disparate objects* , as is integral to this discussion, are likely to have a superclass already. And there is no non-interface MI in java.
...[rip]...
 Signature Everythinginlifeisrealative.Apingpongballseemssmalluntilsomeoneramsitupyournose.
Dale King - 15 Jun 2005 04:44 GMT > "Thomas G. Marshall" <tgm2tothe10thpower@replacetextwithnumber.hotmail.com> [and so on back and forth]
> That marker interfaces often require downcasting in order to accomplish > something. Marker interfaces are only identify some objects out of a larger > collection. I believe that what you do with those objects (and any > downcasting required) is a separate issue. The typical marker interfaces > for Cloneable, etc don't require any downcasting at all. I'm not really taking a side on this, but Cloneable is not really a valid example for the general case of marker interfaces. It doesn't have to downcast because it has its implementation in the common superclass Object. That sort of agrees with Thomas' point because as he was noting that one issue with marker interfaces is that you don't have the common superclass, but in the case of Cloneable you actually do. The same however cannot be said for the general case of marker interfaces.
 Signature Dale King
Thomas G. Marshall - 15 Jun 2005 05:07 GMT Dale King coughed up:
>> "Thomas G. Marshall" >> <tgm2tothe10thpower@replacetextwithnumber.hotmail.com> [quoted text clipped - 16 lines] > do. The same however cannot be said for the general case of marker > interfaces. As I pointed out in my last post, Cloneable is indeed an odd duck that doesn't belong in this conversation, because while /everything/ (marker interface or not) has access to Object, the actual intended usage of Cloneable is for accessing something within Object without downcasting.
There is little wonder that Cloneable causes so much ire, particularly among the purists. Sun apparently did not want a Cloneable.clone() interface method because clone() would need to exist within Object anyway (it is best implemented as something native), Object would need to implement Cloneable, which would mean that every single object in the known universe would be cloneable. {shrug} Which doesn't somehow seem so bad to me.
 Signature Framsticks. 3D Artificial Life evolution. You can see the creatures that evolve and how they interact, hunt, swim, etc. (Unaffiliated with me). http://www.frams.alife.pl/
Stefan Schulz - 15 Jun 2005 05:48 GMT > Dale King coughed up: > There is little wonder that Cloneable causes so much ire, particularly among [quoted text clipped - 3 lines] > which would mean that every single object in the known universe would be > cloneable. {shrug} Which doesn't somehow seem so bad to me. I would at least have expected a public Object clone(); in Cloneable. Leaving the method abstract does make very little sense to me. Okay, so you can, in theory, have the ability to make an Object cloneable without actually exposing the clone() method... but how often does that happen?
 Signature In pioneer days they used oxen for heavy pulling, and when one ox couldn't budge a log, they didn't try to grow a larger ox. We shouldn't be trying for bigger computers, but for more systems of computers. --- Rear Admiral Grace Murray Hopper
Daniel Dyer - 15 Jun 2005 12:20 GMT > As I pointed out in my last post, Cloneable is indeed an odd duck that > doesn't belong in this conversation, because while /everything/ (marker [quoted text clipped - 10 lines] > which would mean that every single object in the known universe would be > cloneable. {shrug} Which doesn't somehow seem so bad to me. Couldn't Sun have included the clone method in the Cloneable interface but also have left the clone method in Object as protected (an not have Object implement Cloneable)? Then any class implementing Cloneable would be forced to over-ride the protected method with a public version. At the moment you have the silly situation where you can implement Cloneable without providing a public clone method, which means you cannot safely invoke clone without knowing the object's concrete type.
The cloning mechanism is broken anyway since you have no control over the cloning of final fields without using a constructor in the clone method, which is not suitable for non-final classes.
Dan.
 Signature Daniel Dyer http://www.footballpredictions.net
Bent C Dalager - 15 Jun 2005 12:54 GMT >Couldn't Sun have included the clone method in the Cloneable interface but >also have left the clone method in Object as protected (an not have Object >implement Cloneable)? Then any class implementing Cloneable would be >forced to over-ride the protected method with a public version. I think this would be solving a different problem from what Sun wanted to solve. The current Cloneable design is useful for handling the implementation of cloning within an inheritance hierarchy, but not for exposing the functionality to the outside world. I think this is exactly what they wanted it to do. It provides inheritable cloneability but keeps it in the family so to speak.
If you also want to expose cloneability to other classes/packages, you're basically on your own.
Cheers Bent D
 Signature Bent Dalager - bcd@pvv.org - http://www.pvv.org/~bcd powered by emacs
Dale King - 16 Jun 2005 14:33 GMT > Dale King coughed up: > [quoted text clipped - 23 lines] > interface or not) has access to Object, the actual intended usage of > Cloneable is for accessing something within Object without downcasting. Yes, that is what I was trying to point out. Matt's use of it as an example is not valid.
Essentially marker interfaces end up relying on some way to go around the declared types and protection to do anything useful. Cloneable does it by putting the implementation in Object. Serialized does it with reflection with special access to access private fields. Remote uses a separate tool that processes the class file. Another possibility is using native methods.
 Signature Dale King
Stefan Schulz - 13 Jun 2005 20:22 GMT On Mon, 13 Jun 2005 11:24:48 -0700, jrefactors wrote:
> I know what is marker interface - An interface with no methods. > Example: Serializable, Remote, Cloneable. [quoted text clipped - 3 lines] > > Please advise. thanks!! For 1.5, i would not use marker interfaces at all anymore. Use a Runtime-Retained annotation.
Generally, they are used to give additional information about the behaviour of a class. The possibly best example is the RandomAccess interface... the worst offender probably Cloneable.
 Signature In pioneer days they used oxen for heavy pulling, and when one ox couldn't budge a log, they didn't try to grow a larger ox. We shouldn't be trying for bigger computers, but for more systems of computers. --- Rear Admiral Grace Murray Hopper
Chris Uppal - 14 Jun 2005 09:13 GMT > For 1.5, i would not use marker interfaces at all anymore. Use a > Runtime-Retained annotation. Just BTW, has anyone looked at the performance of the runtime annotations ?
-- chris
Tor Iver Wilhelmsen - 14 Jun 2005 15:47 GMT > For 1.5, i would not use marker interfaces at all anymore. Use a > Runtime-Retained annotation. Except that
object instanceof MarkerInterface
is easier than
object.getClass().isAnnotationPresent(MarkerAnnotation.class)
Thomas G. Marshall - 15 Jun 2005 00:38 GMT Tor Iver Wilhelmsen coughed up:
>> For 1.5, i would not use marker interfaces at all anymore. Use a >> Runtime-Retained annotation. [quoted text clipped - 6 lines] > > object.getClass().isAnnotationPresent(MarkerAnnotation.class) I think so too. I'm not sure why someone would want to avoid it.
I'm assuming that it has to do with an aversion to the following:
1. RTTI 2. downcasting
But there are times when both are the clearest thing to do.
 Signature Whyowhydidn'tsunmakejavarequireanuppercaselettertostartclassnames....
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|