Java: Rationale of the Object class not being declared abstract - java

Why wasn't the java.lang.Object class declared to be abstract ?
Surely for an Object to be useful it needs added state or behaviour, an Object class is an abstraction, and as such it should have been declared abstract ... why did they choose not to ?

An Object is useful even if it does not have any state or behaviour specific to it.
One example would be its use as a generic guard that's used for synchronization:
public class Example {
private final Object o = new Object();
public void doSomething() {
synchronized (o) {
// do possibly dangerous stuff
}
}
}
While this class is a bit simple in its implementation (it isn't evident here why it's useful to have an explicit object, you could just declare the method synchronized) there are several cases where this is really useful.

Ande, I think you are approaching this -- pun NOT intended -- with an unnecessary degree of abstraction. I think this (IMHO) unnecessary level of abstraction is what is causing the "problem" here. You are perhaps approaching this from a mathematical theoretical approach, where many of us are approaching this from a "programmer trying to solve problems" approach. I believe this difference in approach is causing the disagreements.
When programmers look at practicalities and how to actually implement something, there are a number of times when you need some totally arbitrary Object whose actual instance is totally irrelevant. It just cannot be null. The example I gave in a comment to another post is the implementation of *Set (* == Hash or Concurrent or type of choice), which is commonly done by using a backing *Map and using the Map keys as the Set. You often cannot use null as the Map value, so what is commonly done is to use a static Object instance as the value, which will be ignored and never used. However, some non-null placeholder is needed.
Another common use is with the synchronized keyword where some Object is needed to synchronize on, and you want to ensure that your synchronizing item is totally private to avoid deadlock where different classes are unintentionally synchronizing on the same lock. A very common idiom is to allocate a private final Object to use in a class as the lock. To be fair, as of Java 5 and java.util.concurrent.locks.Lock and related additions, this idiom is measurably less applicable.
Historically, it has been quite useful in Java to have Object be instantiable. You could make a good point that with small changes in design or with small API changes, this would no longer be necessary. You're probably correct in this.
And yes, the API could have provided a Placeholder class that extends Object without adding anything at all, to be used as a placeholder for the purposes described above. But -- if you're extending Object but adding nothing, what is the value in the class other than allowing Object to be abstract? Mathematically, theoretically, perhaps one could find a value, but pragmatically, what value would it add to do this?
There are times in programming where you need an object, some object, any concrete object that is not null, something that you can compare via == and/or .equals(), but you just don't need any other feature to this object. It exists only to serve as a unique identifier and otherwise does absolutely nothing. Object satisfies this role perfectly and (IMHO) very cleanly.
I would guess that this is part of the reason why Object was not declared abstract: It is directly useful for it not to be.

Does Object specify methods that classes extending it must implement in order to be useful? No, and therefor it needn't be abstract.
The concept of a class being abstract has a well defined meaning that does not apply to Object.

You can instantiate Object for synchronization locks:
Object lock = new Object();
void someMethod() {
//safe stuff
synchronized(lock) {
//some code avoiding race condition
}
}
void someOtherMethod() {
//safe code
synchronized(lock) {
//some other stuff avoiding race condition
}
}

I am not sure this is the reason, but it allows (or allowed, as there are now better ways of doing it) for an Object to be used as a lock:
Object lock = new Object();
....
synchronized(lock)
{
}

How is Object any more offensive than null?
It makes a good place marker (as good as null anyway).
Also, I don't think it would be good design to make an object abstract without an abstract method that needs to go on it.
I'm not saying null is the best thing since sliced bread--I read an article the other day by the "Inventor" discussing the cost/value of having the concept of null... (I didn't even think null was inventable! I guess someone somewhere could claim he invented zero..) just that being able to instantiate Object is no worse than being able to pass null.

You never know when you might want to use a simple Object as a placeholder. Think of it as like having a zero in a numerical system (and null doesn't work for this, since null represents the absence of data).

There should be a reason to make a class abstract. One is to prevent clients from instantiating the class and force them into using only subclasses (for whatever reasons). Another is if you wish to use it as an interface by providing abstract methods, which subclasses must implement. Probably, the designers og Java saw no such reasons, so java.lang.Object remains concrete.

As always, Guava comes to help: with http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Optional.html
Stuff here can be used to kill nulls / Object instances for "a not-null placeholder" from the code.
There are entirely seperated questions here:
why did not they make Object abstract?
how much disaster comes after if they decide to make it abstract in a future release?

I'll just throw in another reason that I've found Object to useful to instantiate on its own. I have a pool of objects I've created that has a number of slots. Those slots can contain any of a number of objects, all that inherit from an abstract class. But what do I put in the pool to represent "empty". I could use null, but for my purpose, it made more sense to insure that there was always some object in each slot. I can't instantiate the abstract class to put in there, and I wouldn't have wanted to. So I could have created a concrete subclass of my abstract class to represent "not a useful foo", but that seemed unnecessary when using an instance of Object was just as good..in fact better, as it clearly says that what's in the slot has no functionality. So when I initialize my pool, I do so by creating an Object to assign to each slot as the initial condition of the pool.
I agree that it might have made sense for the original Java crew to have defined a Placeholder object as a concrete subclass of Object, and then made Object abstract, but it doesn't rub me wrong at all that they went the way they did. I would then have used Placeholder in place of Object.

Related

How does one know if a certain method will change the state of a java object?

Some methods are mutator methods, usually they return nothing, the so-called setters. Others, like the .plusDays() method of the LocalDate class, return a full, instantiated object of type Localdate, so if you want to change the object, you need to point your existing object variable to the newly created one.
Is there a way to know beforehand if a method will be a mutator, or work like the before-mentioned apart from looking at its return value?
No, there is no way to know (short of looking at the documentation or implementation) whether a method will change some sort of state.
Methods that return void are generally going to change some sort of state (otherwise what are they doing?), but there's still no guarantee what will change (options include the object, one of its fields, the method's parameters, global state, or even the JVM runtime itself).
There's no general-purpose way to tell whether methods that return something will also have other side-effects or not.
If a type is immutable you can be confident that none of its methods will mutate its own state, but then the question has simply shifted to "how do you tell whether a type is immutable or not?" This is easier to answer, but still tricky. Static analysis tools like ErrorProne's #Immutable check are helpful but still fallible.
Well, pure setters which follow the pattern void setProperty(PropertyType property) are likely to modify the internal state (ok, one could implement it in a different way, e.g. modify the state of the passed parameter, but that would be strange).
Methods found in Builders for instance (like Builder withProperty(PropertyType property)) are free to choose whether they update the state of the actual instance or create and return new instance holding the updated property.
In the end one cannot foresee whether one or the other implementation strategy has been chosen just by looking at the method, so one has to read the docs (and sometimes the code).

How come two method references are compiled into two different addresses?

I reference the same method twice but the references are different. See this example:
import java.util.function.Consumer;
public class MethodRefTest {
public static void main(String[] args) {
new MethodRefTest();
}
public MethodRefTest() {
Consumer<Integer> a = this::method;
System.out.println(a);
Consumer<Integer> b = this::method;
System.out.println(b);
}
public void method(Integer value) {
}
}
The output is:
MethodRefTest$$Lambda$1/250421012#4c873330
MethodRefTest$$Lambda$2/295530567#776ec8df
Are method references nothing more than syntactic sugar for anonymous classes? If not, what do I have to do to always get the same method reference? (Aside from storing a reference once in a field to work with.)
(Application: I thought of method references as a prettier way of observer implementation. But with different references each time it's impossible to remove an observer from an observable once it's added.)
Are method references nothing more than syntactic sugar for anonymous classes?
Correct. They aren't necessarily always implemented as heavyweight as that, but conceptually it's all they are.
If not, what do I have to do to always get the same method reference? (Aside from storing a reference once in a field to work with.)
Store the reference in a field. That's the answer. (Sorry.)
You ask,
Are method references nothing more than syntactic sugar for anonymous classes?
The JLS says that
Evaluation of a method reference expression produces an instance of a functional interface type
(JLS 8, section 15.13)
That doesn't explicitly require an anonymous class, but it does require some class, and it does not provide a mechanism for naming that class. I can imagine alternatives, but using the existing anonymous class mechanism seems pretty natural.
It is plausible that an implementation could recognize multiple references to the same method and use the same anonymous class for them, but such behavior is by no means required, and you have demonstrated that your implementation does not do it. Even if an implementation did do that, however, the JLS is at minimum suggestive that each evaluation of a method reference expression produces a new object.
You go on,
If not, what do I have to do to always get the same method reference? (Aside from storing a reference once in a field to work with.)
Your only guaranteed mechanism is to evaluate the method reference just once, and to then hold on to a reference to the resulting object as long as you have need of it. Storing the reference in a field, as #JohnKugelman describes, is one variation on that, but depending on the scope in which you need to refer to the same method reference object, it might suffice to store it in a local variable or to pass it around via method arguments.
Generally speaking the easiest and efficient way is storing the reference either in a field or a (local) variable.
First of all, the toString() output of the object generated for a method reference is entirely unspecified, hence, you cannot draw any conclusions about the object’s identity from there. Also, the hexadecimal number is an implementation dependent hashcode that is rarely an address. The only reliable way to check the identity of the object is to do a==b.
Still, these objects are indeed different, but that’s an implementation detail. As explained in Does a lambda expression create an object on the heap every time it's executed?, the JVM has a lot of freedom regarding object reuse, but the current HotSpot/OpenJDK implementation will reuse objects only for non-capturing expressions and this::method is capturing the this reference. Also, as shown by the code of your question, each occurrence of this::method in your code will even get its own generated class.
This is explained in Is method reference caching a good idea in Java 8?, which also concludes that you shouldn’t keep these instances for performance reasons. But in your case, when you want to deregister a listener reliably, keeping the reference in a variable is the only way to do it. As even for a single occurrence of a non-capturing expression, for which the current implementation will provide the same object, there is no guaranty that this will work, as this reuse still is an implemen­tation dependent behavior.

Create a hashmap of immutable generic objects

I don't think that there is a way that is efficient (if at all) of doing this, but I figured I'd ask in case someone else knows otherwise. I'm looking to create my own Cache/lookup table. To make it as useful as possible, I'd like it to be able to store generic objects. The problem with this approach is that even though you can make a Collections.unmodifiableMap, immutableMap, etc, these implementations only prevent you from changing the Map itself. They don't prevent you from getting the value from the map and modifying its underlying values. Essentially what I'd need is for something to the effect of HashMap<K, ? extends Immutable>, but to my knowledge nothing like this exists.
I had originally thought that I could just return a copy of the values in the cache in the get method, but since Java's Cloneable interface is jacked up, you cannot simple call
public V getItem(K key){
return (V) map.get(k).clone();
}
Your thinking is good, and you're right that there's no built-in way of handling immutability.
However, you could try this:
interface Copyable<T> {
T getCopy();
}
Then override the get() method to return copies instead of the value itself;
class CopyMap<K, V extends Copyable<V>> extends HashMap<K, V> {
#Override
public V get(Object key) {
return super.get(key).getCopy();
}
}
Then it's up to the implementation to return a copy of itself, rather than this (unless the class itself is immutable). Although you can't enforce that in code, you would be within your rights to publicly humiliate the programmer that doesn't conform.
I'm looking to create my own Cache/lookup table.
Why not use Guava's cache?
The problem with this approach is that even though you can make a
Collections.unmodifiableMap, immutableMap, etc, these implementations
only prevent you from changing the Map itself. They don't prevent you
from getting the value from the map and modifying its underlying
values.
This is not something any collection can enforce for you. You need to make the classes themselves immutable. There is a hacky approach using Reflection (which can also be used to make a class mutable!), but really, you should avoid this and simply create classes that are immutable.
There are other options for object cloning in Java: Making a copy of an object Dynamically?
Be aware though that deep cloning any object might be dangerous. The objects stored in this map must be i.e. isolated from each other, to make sure that whole object graph won't be copied when returning a single entry.
There is no formal concept of "mutability" or "immutability" in the language. The compiler cannot tell whether a type is "mutable" or "immutable". To determine whether something is immutable, we humans have to examine every field and method of the class, and reason through the behavior of the methods to discover that none of them will alter the state of the object, then we call it "immutable". But there is no difference from the perspective of the language.

Is passing 'this' in a method call accepted practice in java

Is it good/bad/acceptable practice to pass the current object in a method call. As in:
public class Bar{
public Bar(){}
public void foo(Baz baz){
// modify some values of baz
}
}
public class Baz{
//constructor omitted
public void method(){
Bar bar = new Bar();
bar.foo(this);
}
}
Specifically, is the line bar.foo(this) acceptable?
There's nothing wrong with that. What is NOT a good practice is to do the same inside constructors, because you would give a reference to a not-yet-completely-initialized object.
There is a sort of similar post here: Java leaking this in constructor
where they give an explanation of why the latter is a bad practice.
There's no reason not to use it, this is the current instance and it's perfectly legitimate to use. In fact there's often no clean way to omit it.
So use it.
As it's hard to convince it's acceptable without example (a negative answer to such a question is always easier to argument), I just opened one of the most common java.lang classes, the String one, and of course I found instances of this use, for example
1084 // Argument is a String
1085 if (cs.equals(this))
1086 return true;
Look for (this in big "accepted" projects, you won't fail to find it.
Yes, but you should be careful about two things
Passing this when the object has not been constructed yet (i.e. in its constructor)
Passing this to a long-living object, that will keep the reference alive and will prevent the this object from being garbage collected.
It's perfectly normal and perfectly acceptable.
this stands for the current object. What you are doing is sytatically correct but i don't see a need of this if you are calling the method in the same class.
It is bad practice to pass the current object in a method call if there less complex alternatives to achieve the same behaviour.
By definition, a bidirectional association is created as soon as this is passed from one object to another.
To quote Refactoring, by Martin Fowler:
Change Bidirectional Association to Unidirectional (200)
Bidirectional associations are useful, but they carry a price. The
price is the added complexity of maintaining the two-way links and
ensuring that objects are properly created and removed. Bidirectional
associations are not natural for many programmers, so they often are a
source of errors
...
You should use bidirectional associations when you need to but not
when you don’t. As soon as you see a bidirectional association is no
longer pulling its weight, drop the unnecessary end.
So, theoretically, we should be hearing alarm bells when we find we need to pass this and try really hard to think of other ways to solve the problem at hand. There are, of course, times when, at last resort, it makes sense to do it.
Also it is often necessary to corrupt your design temporarily, doing 'bad practice things', during a longer term refactoring of your code for an overall improvement. (One step back, two steps forward).
In practice I have found my code has improved massively by avoiding bidirectional links like the plague.
Yes. you can use it.Its just common in programming to pass this.But there are pros and cons about using that.Still it is not hazardous to do so.
Just to add one more example where passing this is correct and follows good design: Visitor pattern. In Visitor design pattern, method accept(Visitor v) is typically implemented in a way it just calls v.visit(this).
Acceptable
Snippet from Oracle JAVA docs:
Within an instance method or a constructor, this is a reference to the
current object — the object whose method or constructor is being
called. You can refer to any member of the current object from within
an instance method or a constructor by using this.
Using this with a Field
The most common reason for using the this keyword is because a field
is shadowed by a method or constructor parameter.
Everything in java is passed by value. But objects are NEVER passed to the method!
When java passes an object to a method, it first makes a copy of a reference to the object, not a copy of the object itself. Hence this is pefectly used method in java. And most commonly followed usage.

Do effectively immutable objects make sense?

In the book Java Concurrency In Practice it explains the advantages of "effectively immutable" objects versus mutable objects concurrency-wise. But it does not explain what advantage "effectively immutables" objects would offer over really immutable objects.
And I don't get it: can't you always build a really immutable object at the moment you'd decide to publish safely an "effectively immutable" object? (instead of doing your "safe publication" you'd build a really immutable object and that's it)
When I'm designing classes I fail to see cases where I couldn't always build a truly immutable object (using delegation if needed etc. to build other wrapped objects, themselves truly immmutable of course) at the moment I'd decide to "safely publish".
So are "effectively immutable" object and their "safe publication" just a case of bad design or poor APIs?
Where would you be forced to use an effectively immutable object and be forced to safely publish it where you couldn't build a much superior really immutable object?
Yes, they make sense in some cases. An easy example is when you want some property to be generated lazily and cached so you can avoid the overhead of generating it if it's never accessed. String is an example of an effectively immutable class that does this (with its hashcode).
For circular immutables:
class Foo
{
final Object param;
final Foo other;
Foo(Object param, Foo other)
{
this.param = param;
this.other = other;
}
// create a pair of Foo's, A=this, B=other
Foo(Object paramA, Object paramB)
{
this.param = paramA;
this.other = new Foo(paramB, this);
}
Foo getOther(){ return other; }
}
// usage
Foo fooA = new Foo(paramA, paramB);
Foo fooB = fooA.getOther();
// publish fooA/fooB (unsafely)
A question is, since this of fooA is leaked inside constructor, is fooA still a thread safe immutable? That is, if another thread reads fooB.getOther().param, is it guaranteed to see paramA? The answer is yes, since this is not leaked to another thread before the freeze action; we can establish hb/dc/mc orders required by spec to prove that paramA is the only visible value for the read.
Back to your original question. In practice there are always constraints beyond the pure technical ones. Initialize everything inside constructor is not necessarily the best option for a design, considering all engineering, operational, political and other human-ish reasons.
Ever wondering why we are fed to think that it is a great supreme idea?
The deeper problem is Java lacks a general cheap fense for safe publication which is cheaper than volatile. Java only has it for final fields; for some reason, that fence is not available otherwise.
Now final carries two independent meanings: 1st, that a final field must be assigned exactly once; 2nd, the memory semantics of safe publication. These two meanings have nothing to do with each other. It is quite confusing to bundle them together. When people need the 2nd meaning, they are forced to accept the 1st meaning too. When the 1st is very inconvenient to achieve in a design, people wonder what they have done wrong - not realizing that it's Java that did wrong.
Bundling of two meanings under one final makes it double plus good, so that apparently we have more reason and motivation to use final. The more sinister story is actually we are forced to use it because we are not given a more flexible choice.
Using effectively immutable objects lets you avoid creating a considerable number of classes. Instead of making pairs of [mutable builder]/[immutable object] classes, you can build one effectively immutable class. I usually define an immutable interface, and a mutable class that implements this interface. An object is configured through its mutable class methods, and then published through its immutable interface. As long as the clients of your library program to the interface, to them your objects remain immutable through their published lifetime.
Suppose one has an immutable class Foo with five properties, named Alpha, Beta, etc., and one wishes to provide WithAlpha, WithBeta, etc. methods which will return an instance which is identical to the original except with the particular property changed. If the class is truly and deeply immutable, the methods have to take the form:
Foo WithAlpha(string newAlpha)
{
return new Foo(newAlpha, Beta, Gamma, Delta, Epsilon);
}
Foo WithBeta(string newBeta)
{
return new Foo(Alpha, NewBeta, Gamma, Delta, Epsilon);
}
Ick. A massive violation of "Don't Repeat Yourself" (DRY) principles. Further, adding a new property to the class would require adding it to every single one of those methods.
On the other hand, if each Foo held an internal FooGuts which included a copy constructor, one could instead do something like:
Foo WithAlpha(string newAlpha)
{
FooGuts newGuts = new FooGuts(Guts); // Guts is a private or protected field
newGuts.Alpha = newAlpha;
return new Foo(newGuts); // Private or protected constructor
}
The number of lines of code for each method has increased, but the methods no longer need to make any reference to any properties they aren't "interested" in. Note that while a Foo might not be immutable if its constructor were called with a FooGuts to which any outside reference existed, its constructor is only accessible to code which is trusted not to maintain any such reference after construction.

Categories

Resources