aspose file tools*
The moose likes Beginning Java and the fly likes Implicit properties of interface members... Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Implicit properties of interface members..." Watch "Implicit properties of interface members..." New topic
Author

Implicit properties of interface members...

Leroy J Brown
Ranch Hand

Joined: Dec 02, 2007
Posts: 71
Hokay,

So I took a test yesterday at a java training course my company stuck me in and there were some questions that I was surprised to learn that I hadn't previously learned about.

The basic idea is that there are some properties that members of interfaces have 'gardless of whether you declare them or not.

Interface methods are always public, static, final?
Interface variables are always public static?


Do I have this right and can someone help me out with the logic behind designing the language this way? Do abstract methods have any of these implicit modifiers? Memorizing facts by wrote never works for me but if I get why it was done that way I can remember by following their logic.

Thanks
Mark Vedder
Ranch Hand

Joined: Dec 17, 2003
Posts: 624

Originally posted by Tristan Rouse:

Interface methods are always public, static, final?


That would be incorrect. The part about Interface methods always being public is correct; it only makes sense that they are. Since an interface's purpose is to provide a known way of interacting with outside classes. However, methods declared in an interface can never be static; and they cannot be final. The final part makes sense because if a method was final in the interface, how would (or could) it be implemented it in the implementing class? The class that implements an interface can make the implementing method final so any subclasses cannot override that implementation. Lastly, an interface method cannot be static. Again, this is because an interface defines the behavior of an object.

Originally posted by Tristan Rouse:

Interface variables are always public static?

An interface cannot have variables declared in them. An interface defines behavior (and therefore methods), not implementations or data (meaning properties or variables).

Originally posted by Tristan Rouse:

The basic idea is that there are some properties that members of interfaces have 'gardless of whether you declare them or not.


Assuming 'gardless means regardless, and by "members of interfaces" you mean "implementations of interfaces, I am not sure to what you might be referring. Interfaces do not have properties.
[ July 26, 2008: Message edited by: Mark Vedder ]
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19696
    
  20

Originally posted by Tristan Rouse:
Interface methods are always public, static, final?
Interface variables are always public static?

Interfaces themselves are always abstract, although you can omit the word. Don't ask me why; I understand but cannot explain it.

Interface methods are always public and abstract, but never static, final or synchronized.
They are abstract because they cannot have a body. A body is an implementation "detail", something interfaces can never have by design.
They cannot be static because any static method must have an implementation - and as I said before, that's not allowed in an interface. The combination static and abstract is not allowed for any method.
They cannot be final because that means that they cannot be overridden - or implemented. Yet they must be implemented. The combination final and abstract is not allowed - at all, not even for classes. It does not make sense to specify a class is abstract if it can never be subclassed.
They cannot be synchronized because synchronization is an implementation detail.

Interface variables are always public, static and final.
Because they are static and final, they are constants. Any other type of variable is an implementation detail - and there can be no implementation details in interfaces.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19696
    
  20

Originally posted by Mark Vedder:
An interface cannot have variables declared in them. An interface defines behavior (and therefore methods), not implementations or data (meaning properties or variables).

An interface can have variables, but only if they are constants - static and final, which they will be by default. They are required to be initialized immediately, e.g. "int CONSTANT = 0".
Mark Vedder
Ranch Hand

Joined: Dec 17, 2003
Posts: 624

Originally posted by Rob Prime:

An interface can have variables, but only if they are constants - static and final, which they will be by default. They are required to be initialized immediately, e.g. "int CONSTANT = 0".


Interesting. I never knew that. Thanks Rob.
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3014
    
  10
[Note - much of this was written before seeing Rob's replies above.]

[Tristan]:
Interface methods are always public, static, final?
Interface variables are always public static?


No.

Interface methods are always public, never static, never final.
Interface variables are always public static, and final.

For methods, the whole point of an interface method is that its declaration must be overridden by a class that implements the interface. (Unless the class is abstract, in which it defers the implementation to subclasses.) You can't override the method declaration if it's static, and you can't override it if it's final.

For variables, interfaces are only allowed to define "constants" - a term I use in quotes because what's allowed in an interface is more than just compile-time constants - and even includes mutable objects. Which in my opinion means it's not a constant at all, and someone at Sun was smoking crack when they wrote that section of the JLS. I mean, this is perfectly legal:

The field "supposedlyConstant" is, indeed, public, static, and final, despite not being declared as any of those. But it's not exactly a constant, as most people would understand the term. Or to look at it another way - the reference always points to the same object, but the object itself is very much mutable.

Rob - so would you call this a "runtime constant" then?

[Tristan]: Assuming 'gardless means regardless, and by "members of interfaces" you mean "implementations of interfaces, I am not sure to what you might be referring. Interfaces do not have properties.

I would assume that "members of interfaces" means members of interfaces. Which do have properties, in the sense that they have characteristics which can be meaningfully discussed. The don't have properties in the sense that JavaBeans have properties, but they do have properties.
[ July 26, 2008: Message edited by: Mike Simmons ]
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3014
    
  10
[Rob]: [...] and there can be no implementation details in interfaces.

Unless, perhaps, you put an entire nested class into the interface. Which is entirely possible.

Interfaces are primarily intended for things other than implementation details. But there are ways to sneak them in there. Without even being sneaky. It would be fair to say that method declarations in interfaces do not have any implementation details. Field declarations and nested type declarations certainly can have implementation details.
[ July 26, 2008: Message edited by: Mike Simmons ]
Leroy J Brown
Ranch Hand

Joined: Dec 02, 2007
Posts: 71
Thank you very much for the replies.

I have one tangential question that relates to the code MS showed. Thinking about that makes perfect sense. supposedlyConstant holds the address of an object and the address is constant, not the fields of the object.

It does make me curious though if there is a way to make an object's fields constant, not including trivial things like writing an object with all fields static and final, but taking an object that already exists as a class in the API say, and using it as a constant in the way that a naive person would expect supposedlyConstant to behave.

Is that possible in java?
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3014
    
  10
No, as far as I know there's no way to do that in Java. To make a class immutable, you need to make all fields final, and either primitive types, or references to other immutable types. Well, maybe you don't need to make the fields final if you simply do not provide any mutator methods - but that invites trouble with thread safety, as it's difficult to guarantee that all threads will see the same unchanging values, unless you use either final, or some form of synchronization. Using final fields is by far the simplest.

The static keyword doesn't really have anything to do with being immutable, or constant. Except that most compile-time constants are static for the simple reason that there's no point to being non-static, if all instances hold the exact same value. Nonetheless, it's entirely possible to have a compile-time constant that is referred to with an instance variable, or a local variable. Being final is important here. Being static is not.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Originally posted by Mike Simmons:
No, as far as I know there's no way to do that in Java. To make a class immutable, you need to make all fields final, and either primitive types, or references to other immutable types. Well, maybe you don't need to make the fields final if you simply do not provide any mutator methods


Making an Immutable class isn't that hard. The general concept would be:
1) No Mutator methods
2) Any reference to an object must be
-a) to an immutable object - or -
-b) a local solely possessed reference, such as:
--i) an object generated within the immutable class itself (not passed in to the constructor or set as a static variable)
--ii) a clone or copy of an object passed in to object from an outside source

Show, for example, String, which has a char[] to hold the contents. A char[] is not immutable, but because it is solely referenced by the String and the String provides no mutator methods for it, there is no thread issues. You can provide a char[] to one of the String constructors, but because the String makes a copy of the array it holds internally, changing the char[] once the String is constructed does not change the String.

The biggest worry in item ii) is if you do rely on a class that is passed in and you try to clone or copy it, is that you do a deep clone/copy to be sure it doesn't provide a loop hole for the immutability.

Originally posted by Mike Simmons:
- but that invites trouble with thread safety, as it's difficult to guarantee that all threads will see the same unchanging values, unless you use either final, or some form of synchronization. Using final fields is by far the simplest.


This is true, though if the accessor to the property in question is idempotent then thread safety is not an issue. Specifically I am thinking of immutable classes that use lazy initialization of data (would be costly to generate, and is not always needed, so hold off generating it till the data is actually used). In these cases you wouldn't want the field to be final, but the process of retrieving the data should return the same result 1) regardless of when it is executed and 2) regardless of how often it is executed. Ideally the expensive work would be executed once and the data cached locally, but in multiple threads it may be called multiple times, cached in the thread-local copy of the object until the thread-local copies are reconciled with each other. It may cost resources but should not cause inconsistency.

Now that I think about it, idempotency should be the major descriptor for an immutable object. Once the initial context is defined (the constructor is called with its necessary arguments) then ALL the actions of the class should return the same results regardless of when the action is executed, and how often it is executed.


Steve
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3014
    
  10
Steve: Hm, I don't think idempotence is really the issue. Consider:

This class may look thread-safe and immutable, but it isn't. Because x is not final, it's possible for other threads to observe an object with a different value of x - like say 0, the default value for an int. This is described in the JLS here. In their class FinalFieldExample, the field x is safe, because it's final, but the field y is not.

And this is not an issue of idempotence - the value of the field does not depend in the number of invocations of getX(); it depends on when the method is invoked, how the thread schedule works, how data is cached between threads, and other things outside our control. The value of x does not change in response to getX(), but it does change for other reasons.

It's possible to perform lazy loading, which necessarily means that the field to be loaded must not be final - but then you need other tricks, like double-checked locking with a volatile flag. (A good excuse to recommend Effective Java, 2nd Edition to anyone who hasn't picked it up.) But aside from more complex techniques like that, it's much easier in general to simply use final. Merely having methods that look like they don't change the value of a field is not enough.
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3014
    
  10
[Steve]: Making an Immutable class isn't that hard.

To clarify: Tristan indicated he already knew the technique of making fields final. He wanted a way to take a class that already exists in the API (presumably, not an already-immutable class) and make it behave as a constant. Like, say, the freeze() method in Ruby. That's what I said is not possible in Java. I didn't go into full detail about the standard techniques of how to make a class immutable, if you're the one writing the class - because that wasn't what Tristan's question was about. And it's discussed in detail in most introductory Java books anyway, except perhaps for the thread safety issues, which are less obvious.
[ July 26, 2008: Message edited by: Mike Simmons ]
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Originally posted by Mike Simmons:
To clarify: Tristan indicated he already knew the technique of making fields final. He wanted a way to take a class that already exists in the API (presumably, not an already-immutable class) and make it behave as a constant.


Sorry I went a bit off topic...


Originally posted by Mike Simmons:
It's possible to perform lazy loading, which necessarily means that the field to be loaded must not be final - but then you need other tricks, like double-checked locking with a volatile flag. (A good excuse to recommend Effective Java, 2nd Edition to anyone who hasn't picked it up.)


Actually, this is the case why I brought up idempotent code. It is not necessary to provide synchronized checks if the value returned is the same with every call. Synchronization only matters if the value can change. If thread1 sees a null object, it generates a value for it then returns it. If thread2 executes before thread1 finishes generating a value then it also generates a value for the object and returns it. Yes, the value for the object was generated twice but if the contents are the same there is no issue. A very common example of lazy-loading in immutable classes is the hashCode() method which needs no synchronization.
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3014
    
  10
It's true that it's possible to do this without synchronization, particularly if there's no requirement that a calculation never be repeated (as long as it's a reasonably uncommon occurrence). Nonetheless I think it's dangerous to say "if the accessor to the property in question is idempotent then thread safety is not an issue. " You need to understand thread safety in order to evaluate whether a method is truly idempotent, which means thread safety is an issue. It's too easy to write non-idempotent methods otherwise. As shown above - the getX() method in Foo certainly looks idempotent, unless you understand the threading issues.

As an aside, I note that "idempotent" is often misunderstood, and the definition given in the HTTP spec is a lot more vague than what you might expect from a strict mathematical background. See here for more discussion of this. You seem to be assuming a strict definition, as did Pat, which is fine - I have tried to match your usage here. But beware that the term's definition has become a good deal looser among web programmers, thanks to the HTTP spec.

Specifically, it's not at all clear whether the term applies to method whose return value changes over time, but not as a function of the number of invocations (where n >= 1). If you do a GET on Google news, what you see depends on what's in the news at the time you did the GET. It does not depend on how many times you did GET before that. The HTTP spec tells us that "a sequence that never has side effects is idempotent, by definition" - which ignores the possibility that a return value might have changed over time, not as a side effect of a previous invocation of the method. As a result, the definition of "idempotent" has become somewhat corrupted among web programmers, and can't really be trusted.

Your statement that "if the accessor to the property in question is idempotent then thread safety is not an issue" relies on this definition. Your proposed solution relies on the programmer using a strict mathematical definition of idempotence - a return value for an idempotent method (function, in this case) should never change, ever, for any reason. But that's not how many web programmers would see such a statement. They would often figure that if the method didn't have any side effects, didn't change any data - then the method is idempotent. Again, blame the HTTP spec. But that's why I disagreed with your statements about idempotence. They're true, but only if you use a strict (non-HTTP-spec) definition of the word. And readers really need to understand threading issues in order to implement idempotent methods. So "if the accessor to the property in question is idempotent then thread safety is not an issue " basically reduces to "if you know how to avoid threading issues, then threading issues are not a problem". Well, duh. That's true, but essentially useless unless you provide concrete examples.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Originally posted by Mike Simmons:
It's true that it's possible to do this without synchronization, particularly if there's no requirement that a calculation never be repeated (as long as it's a reasonably uncommon occurrence).


Agree. If the accessor is called often, then you probably are better off not using lazy loading anyway...

Originally posted by Mike Simmons:
Nonetheless I think it's dangerous to say "if the accessor to the property in question is idempotent then thread safety is not an issue. " You need to understand thread safety in order to evaluate whether a method is truly idempotent, which means thread safety is an issue. ...
And readers really need to understand threading issues in order to implement idempotent methods. So "if the accessor to the property in question is idempotent then thread safety is not an issue " basically reduces to "if you know how to avoid threading issues, then threading issues are not a problem". Well, duh. That's true, but essentially useless unless you provide concrete examples.


OK, true enough, it is circular, but just about any discussion of thread safety ends up circular("What is a thread safe class?" "One that behaves as expected under heavy thread load" "Well no duh...").

...

I was going to go into details here, but it was getting way too much for a beginner's forum - and has drifted off topic enough. To the OP, sorry for dragging this so far from what you had asked.

Originally posted by Mike Simmons:
[QB]As an aside, I note that "idempotent" is often misunderstood, and the definition given in the HTTP spec is a lot more vague than what you might expect from a strict mathematical background. See here for more discussion of this. You seem to be assuming a strict definition, as did Pat, which is fine - I have tried to match your usage here. But beware that the term's definition has become a good deal looser among web programmers, thanks to the HTTP spec.[QB]


Yeah, that is unfortunate. If the term caused confusion I apologize and thanks for clearing that up.
Garrett Rowe
Ranch Hand

Joined: Jan 17, 2006
Posts: 1296
Originally posted by Mike Simmons:
Steve: Hm, I don't think idempotence is really the issue. Consider:

This class may look thread-safe and immutable, but it isn't. Because x is not final, it's possible for other threads to observe an object with a different value of x - like say 0, the default value for an int. This is described in the JLS here. In their class FinalFieldExample, the field x is safe, because it's final, but the field y is not.

The code listed in the JLS is not equivalent to the code presented here. I'm not convinced that thread safety is an issue with that code.


Some problems are so complex that you have to be highly intelligent and well informed just to be undecided about them. - Laurence J. Peter
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3014
    
  10
[Garrett]: The code listed in the JLS is not equivalent to the code presented here.

Well, I think it is, to the extent that it replicates the critical thread-safety bug. What do you think is significantly different? I didn't bother showing code that creates and reads the objects from different threads, as that code can all exist outside the Foo class. Just as the JLS example didn't bother to show code that actually created multiple threads- the point is, once you've got public constructors and methods, it's easy for users to create that stuff outside your class. That's what's fundamentally unsafe here: the lack of final creates an opportunity for different threads to see different values.
[ July 28, 2008: Message edited by: Mike Simmons ]
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Implicit properties of interface members...