Related
I went through a coding problem in a course I'm taking, and I didn't realize that I needed to include my own constructor until I saw the instructor's solution. This has happened a few times throughout the course: I don't expect that I need a constructor, but it turns out I do need one, according to the answer given (below is one of the answers given to me).
I'm wondering now: do I need to make my own constructors when I need to pass parameters and/or I need additional functionality inside the constructor? Are there other situations when relying on the default constructor would be problematic?
private MenuIterator() {
menuIterator = menu.iterator();
calculateNumMenuItems();
}
You need a constructor exactly when you need to perform some sort of setup for your class and field initialization isn't enough. Your described constructor makes no sense because there's no way for your constructor to get menu (and the private modifier prevents you from calling new MenuIterator() in the usual fashion).
The answer given by chrylis is correct. You may also find this discussion of default constructors useful: Java default constructor. Essentially, if you provide any constructor at all (even a no-arg constructor), you will no longer be provided with a default constructor.
If you need to do anything other than call the class' superclass constructor, you will need to supply your own constructor.
Maybe slightly advanced. In addition to what #chrylis said you also need an explicit constructor if you need the constructor to be anything else than public. This is the case if you want the clients of your class to obtain an instance through a static factory method and not use the constructor directly. The Singleton pattern is just one of many uses of a static method for obtaining an instance.
I wouldn’t worry too much. Even though your instructor has a fine solution with a constructor, it could well be that you have a fine solution without a constructor. Programming problems can always be solved in more than one way.
Links
Java Constructors vs Static Factory Methods
Singleton pattern
This is just a quick question to settle a dispute that I stumbled on a while back (sorry I don't have the link).
How I have been declaring object is as so:
class Foo {
private Bar aBar = new Bar();
...
}
Now the dispute that I found says that this is bad Java. I have no idea why he would say that, but he was quite adamant. What he proposed was that all objects should be declared in the class body, but not instantiated until the constructor. Can anyone shed light on this for me? Is it indeed better to instantiate objects in the constructor?
TFYT
~Aedon
Edit 1:
I know that I used the word dispute, but I do not intend for this to be argumentative.
In most cases it doesn't matter. My rule of thumb is:
If you're going to use the same expression to initialize the variable in all constructors, and it doesn't rely on any parameters, do it at the point of declaration.
Otherwise, you're pretty much forced to do it in the constructor anyway.
Reasoning: by initializing at the point of declaration, it's clear that the value is going to be assigned the same way regardless of the constructor and parameters. It also keeps your constructors simpler, and free of duplication.
Caveat: Don't also assign the value in a constructor, as otherwise that invalidates the previous clarity :)
I suggest you ask your colleague (or whatever) for concrete reasons for his claims that your current code is "bad". I'm sure there are valid alternative points of view, but if he can't provide any reasons, then there's no reason to pay attention IMO.
Another quick note - I'm assuming that none of the initializers need to do any significant work. If they do, that could be a point of confusion, especially if exceptions are thrown. In general, I don't like my constructors doing a lot of work.
By assigning properties in the constructor, it becomes immediately clear what code will run when you instantiate your class.
If you assign inside a field declaration, people reading the class constructor won't realize that the field is set elsewhere.
The contract of a constructor is to create an instance that is semantically valid. That is all fields are properly initialized to reasonable values and so on. For this reason, initializing everything in the constructor helps to clarify what makes a valid instance of your class. In addition, mechanisms like constructor chaining can be used to avoid repeating the same code when you have multiple constructors.
However, that is just a textbook-like theory and in real life you sometimes do the more expedient thing. Since it will make almost no difference if you instantiated objects at the point of declaration or not there need be no strong positions that leads to disputes.
I have always felt that in general the main work of a class should be done in its instance methods, while the constructor should only get the instance into a usable inital state.
But I find that in practice there are situations where it seems to make more sense to put essentially all the actual work into the constructor.
One example: I need to retrieve some DBMS-specific information from the database. The most natural way to me seemed to have a class DBMSSpecInfo, with a constructor:
public DBMSSpecInfo(java.sql.Connection conn) throws SQLException{
// ... retrieve info from DBMS
}
/** #returns max size of table in kiB */
public int getMaxTableSize() {//...}
/** #returns max size of index in kiB */
public int getMaxIndexSize() {//...}
/** #returns name of default schema */
public String getDefaultSchema() {//...}
You would construct the class once, the constructor would fetch all data, then you could use various getters to retrieve the info you need.
Of course I could put the method somewhere else, and only use DBMSSpecInfo for the return value (essentially using DBMSSpecInfo only as a value holder), but it feels ugly to create a class just for returning values from a single function.
So what do you think? Are there problems with performing the main work in the constructor? Is it "un-idiomatic" in Java? Or is it an acceptable (though possibly uncommon) practice?
The main practical problem is unit-testing - you won't be able to instantiate the object without doing actual work. (Or you'd have to mock all the classes that participate in this work).
Related talk: OO Design for testability. It gives examples of why doing work in constructors is bad for unit-testing.
I would prefer separating the creation code from the class itself in such cases. It could be put into a static factory method, or a separate factory class (which can also be a public static inner class). The choice depends on the complexity of the code and the design context (which we don't know in this case).
This would also allow you to do optimizations, like caching and reusing the class instance(s).
I'm big on pragmatism. If it works, do it! But in the name of purity and goodness, I'd like to make a design suggestion:
This class muddles up the data content with the mechanism for retrieving it. The object you end up using elsewhere is interesting only for the data it contains. So the "clean" thing to do would be to have a different class for digging out the information and then creating instances of this properties object.
That other class could have a longer lifetime, as you'd typically be calling a method to do the work, not the constructor. The constructor of DBMSSpecInfo might end up assigning a bunch of properties but not doing a lot of error-capable DB access work.
In your example I would make a static method GetDBMSSpecInfo(java.sql.Connection conn) that will return an instance of DBMSSpecInfo object or null if something goes wrong (in case you don't want to throw exceptions).
The DBMSSpecInfo object for me should not contain nothing more than get properties: MaxIndexSize, MaxTableSize, DefaultSchema, etc.
And I would make the constructor of this object private so that instances can only be created from the static method.
I don't think it is a good idea to do the main work in a constructor, since it doesn't have a return value. So it makes error processing more complicated IMO, since it forces you to use exceptions.
A disadvantage of doing the work in the constructor is that constructors can not be overridden (nor should they delegate to overridable methods).
Another is that a constructor is all-or-nothing. If the object contains data whose initializations exhibit indepedent failures, you deprive yourself of the capability to use what data could be procured successfully. Similarly, that you have to initialize the entire object, even if you just need part of it, might adversely affect performance.
On the other hand, doing it in the constructor allows initialization state (here: the connection to the database) to be shared, and released earlier.
As always, different approaches are preferable in different circumstances.
Doing all the work in the constructor can lead to "overload hell". You keep wanting to add more features and instead of just adding a new method, like you would in normal Object-Oriented development, you find yourself adding more and more overloaded constructors. Eventually, the constructors can grow so many overloads and parameters that it becomes unwieldy.
Just be careful that the object is not cloned/deserialised. Instances created this way do not use the constructor.
In my opinion the constructor should be lightweighted and should not throw exceptions.
I'd implement some kind of Load() method to retreive data from the database, or implement lazy loading.
No problem. JDK has a lot of classes that does network IO in constructors.
Lets assume that a rule (or rule of thumb, anyway), has been imposed in my coding environment that any method on a class that doesn't use, modify, or otherwise need any instance variables to do its work, be made static. Is there any inherent compile time, runtime, or any other disadvantage to doing this?
(edited for further clarifications)
I know the question was somewhat open ended and vague so I apologize for that. My intent in asking was in the context of mostly "helper" methods. Utility classes (with private CTORs so they can't be instantiated) as holders for static methods we already do. My question here was more in line of these little methods that HELP OUT the main class API.
I might have 4 or 5 main API/instance methods on a class that do the real work, but in the course of doing so they share some common functionality that might only be working on the input parameters to the API method, and not internal state. THESE are the code sections I typically pull out into their own helper methods, and if they don't need to access the class' state, make them static.
My question was thus, is this inherently a bad idea, and if so, why? (Or why not?)
In my opinion, there are four reasons to avoid static methods in Java. This is not to say that static methods are never applicable, only to say that they should generally be avoided.
As others have pointed out, static methods cannot be mocked out in a unit test. If a class is depending on, say, DatabaseUtils.createConnection(), then that dependent class, and any classes that depend on it, will be almost impossible to test without actually having a database or some sort of "testing" flag in DatabaseUtils. In the latter case, it sounds like you actually have two implementations of a DatabaseConnectionProvider interface -- see the next point.
If you have a static method, its behavior applies to all classes, everywhere. The only way to alter its behavior conditionally is to pass in a flag as a parameter to the method or set a static flag somewhere. The problem with the first approach is that it changes the signature for every caller, and quickly becomes cumbersome as more and more flags are added. The problem with the second approach is that you end up with code like this all over the place:
boolean oldFlag = MyUtils.getFlag();
MyUtils.someMethod();
MyUtils.setFlag( oldFlag );
One example of a common library that has run into this problem is Apache Commons Lang: see StringUtilsBean and so forth.
Objects are loaded once per ClassLoader, which means that you could actually have multiple copies of your static methods and static variables around unwittingly, which can cause problems. This usually doesn't matter as much with instance methods, because the objects are ephemeral.
If you have static methods that reference static variables, those stay around for the life of the classloader and never get garbage collected. If these accumulate information (e.g. caches) and you are not careful, you can run into "memory leaks" in your application. If you use instance methods instead, the objects tend to be shorter-lived and so are garbage-collected after a while. Of course, you can still get into memory leaks with instance methods too! But it's less of a problem.
Hope that helps!
The main disadvantage is that you cannot swap, override or choose method implementations at runtime.
The performance advantage is likely negligible. Use static methods for anything that's not state dependent. This clarifies the code, as you can immediately see with a static method call that there's no instance state involved.
Disadvantage -> Static
Members are part of class and thus remain in memory till application terminates.and can't be ever garbage collected. Using excess of static members sometime predicts that you fail to design your product and trying to cop of with static /procedural programming. It denotes that object oriented design is compromised.This can result in memory over flow.
I really like this question as this has been a point I have been debating for last 4 years in my professional life. Static method make a lot of sense for classes which are not carrying any state. But lately I have been revised my though somewhat.
Utility classes having static methods is a good idea.
Service classes carrying business logic can be stateless in many cases. Initially I always added static methods in them, but then when I gained more familiarity with Spring framework (and some more general reading), I realized these methods become untestable as an independent unit as u cannot inject mock services easily into this class. E.g. A static method calling another static method in another class, there is no way JUnit test can short circuit tis path by injecting a dummy implementation at run time.
So I kind of settled to the thought that having utility static methods which do not need to call other classes or methods pretty much can be static. But service classes in general should be non static. This allows you to leverage OOPs features like overriding.
Also having a singleton instance class helps us to make a class pretty much like a static class still use OOPs concepts.
It's all a question of context. Some people have already given examples where static is absolutely preferable, such as when writing utility functions with no conceivable state. For example, if you are writing a collection of different sort algorithms to be used on arrays, making your method anything but static just confuses the situation. Any programmer reading your code would have to ask, why did you NOT make it static, and would have to look to see if you are doing something stateful to the object.
public class Sorting {
public static void quiksort(int [] array) {}
public static void heapsort(int[] array) { }
}
Having said that, there are many people who write code of some kind, and insist that they have some special one-off code, only to find later that it isn't so. For example, you want to calculate statistics on a variable. So you write:
public class Stats {
public static void printStats(float[] data) { }
}
The first element of bad design here is that the programmer intends to just print out the results, rather than generically use them. Embedding I/O in computation is terrible for reuse. However, the next problem is that this general purpose routine should be computing max, min, mean, variance, etc. and storing it somewhere. Where? In the state of an object. If it were really a one-off, you could make it static, but of course, you are going to find that you want to compute the mean of two different things, and then it's awfully nice if you can just instantiate the object multiple times.
public class Stats {
private double min,max,mean,var;
public void compute(float data[]) { ... }
public double getMin() { return min; }
public double
}
The knee jerk reaction against static is often the reaction of programmers to the stupidity of doing this sort of thing statically, since it's easier to just say never do that than actually explain which cases are ok, and which are stupid.
Note that in this case, I am actually using the object as a kind of special-purpose pass by reference, because Java is so obnoxious in that regard. In C++, this sort of thing could have been a function, with whatever state passed as references. But even in C++, the same rules apply, it's just that Java forces us to use objects more because of the lack of pass by reference.
As far as performance goes, the biggest performance increase of switching from a regular method is actually avoiding the dynamic polymorphic check which is the default in java, and which in C++ is specified manually with virtual.
When I tried last there was a 3:1 advantage of calling a final method over a regular method, but no discernible for calling static functions over final.
Note that if you call one method from another, the JIT is often smart enough to inline the code, in which case there is no call at all, which is why making any statement about exactly how much you save is extremely dangerous. All you can say is that when the compiler has to call a function, it can't hurt if it can call one like static or final which requires less computation.
The main problem you may face is, you won't be able to provide a new implementation if needed.
If you still have doubts ( whether your implementation may change in the future or not ) you can always use a private instance underneath with the actual implementation:
class StringUtil {
private static StringUtil impl = new DefaultStringUtil();
public static String nullOrValue( String s ) {
return impl.doNullOrValue();
}
... rest omitted
}
If for "some" reason, you need to change the implementation class you may offer:
class StringUtil {
private static StringUtil impl = new ExoticStringUtil();
public static String nullOrValue( String s ) {
return impl.doNullOrValue(s);
}
... rest omitted
}
But may be excessive in some circumstances.
No, actually the reason for that advice is that it provides a performance advantage. Static methods can be called with less overhead so any method that doesn't need a reference to this ought to be made static.
No there is no disadvantages, rather when you are not accessing any instance members in the method then there is no meaning of having it as an instance method. It is good programming skill to have it as a static method.
and adding to that you don't have to create any instances to access these methods and thus saving a memory and garbage collecting time.
In order to call the static methods you don't need to create class objects. The method is available immediately.
Assuming the class is already loaded. Otherwise there's a bit of a wait. :-)
I think of static as a good way to separate the functional code from procedural/state-setting code. The functional code typically needs no extension and changes only when there are bugs.
There's also the use of static as an access-control mechanism--such as with singletons.
One disadvantage is if your static methods are general and distributed in different classes as far as usage is concerned. You might consider putting all static methods that are general in a utility class.
There shouldn't be any disadvantages--there may even be a slight advantage in performance (although it wouldn't be measurable) since the dynamic lookup can be avoided.
It's nice to tag functions as functions instead of having them look like Methods--(and static "Methods" ARE functions, not methods--that's actually by definition).
In general a static method is a bad OO code smell--it probably means that your OO model isn't fully integrated. This happens all the time with libraries that can't know about the code that will be using it, but in integrated non-library code static methods should be examined to evaluate which of it's parameters it's most closely associated with--there is a good chance it should be a member of that class.
If a static method just takes native values, then you're probably missing a handful of classes; you should also keep passing native variables or library objects (like collections) to a minimum--instead containing them in classes with business logic.
I guess what I'm saying is that if this is really an issue, you might want to re-examine your modeling practices--statics should be so rare that this isn't even an issue.
As others have said, it provides a slight performance advantage and is good programming practice. The only exception is when the method needs to be an instance method for overriding purposes, but those are usually easily recognised. For example if a class provides default behaviour of an instance method, that happens not to need instance variables, that clearly can't be made static.
In general:
You should be writing your software to take advantage of interfaces and not implementations. Who's to say that "now" you won't use some instance variable, but in the future you will? An example of coding to interfaces...
ArrayList badList = new ArrayList(); //bad
List goodList = new ArrayList(); //good
You should be allowed to swap implementations, especially for mocking & testing. Spring dependency injection is pretty nice in this respect. Just inject the implementation from Spring and bingo you have pretty much a "static" (well, singleton) method...
Now, those types of APIs that are purely "utility" in purpose (i.e., Apache Commons Lang) are the exception here because I believe that most (if not all) of the implementations are static. In this situation, what are the odds that you will want to ever swap Apache Commons out for another API?
Specifically:
How would you elegantly handle the "staticness" of your implementation when you're targeting, say, a Websphere vs. Tomcat deployment? I'm sure there would be an instance (no pun intended) of when your implementation would differ between the two...and relying on a static method in one of those specific implementations might be dangerous...
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java: Rationale of the Object class not being declared abstract
Why is the Object class, which is base class of 'em all in Java, not abstract?
I've had this question for a really really long time and it is asked here purely out of curiosity, that's all. Nothing in my code or anybody's code is breaking because it is not abstract, but I was wondering why they made it concrete?
Why would anyone want an "instance" (and not its presence a.k.a. Reference) of this Object class? One case is a poor synchronization code which uses the instance of an Object for locking (at least I used it this way once.. my bad).
Is there any practical use of an "instance" of an Object class? And how does its instantiation fit in OOP? What would have happened if they had marked it abstract (of course after providing implementations to its methods)?
Without the designers of java.lang.Object telling us, we have to base our answers on opinion. There's a few questions which can be asked which may help clear it up.
Would any of the methods of Object benefit from being abstract?
It could be argued that some of the methods would benefit from this. Take hashCode() and equals() for instance, there would probably have been a lot less frustration around the complexities of these two if they had both been made abstract. This would require developers to figure out how they should be implementing them, making it more obvious that they should be consistent (see Effective Java). However, I'm more of the opinion that hashCode(), equals() and clone() belong on separate, opt-in abstractions (i.e. interfaces). The other methods, wait(), notify(), finalize(), etc. are sufficiently complicated and/or are native, so it's best they're already implemented, and would not benefit from being abstracted.
So I'd guess the answer would be no, none of the methods of Object would benefit from being abstract.
Would it be a benefit to mark the Object class as abstract?
Assuming all the methods are implemented, the only effect of marking Object abstract is that it cannot be constructed (i.e. new Object() is a compile error). Would this have a benefit? I'm of the opinion that the term "object" is itself abstract (can you find anything around you which can be totally described as "an object"?), so it would fit with the object-oriented paradigm. It is however, on the purist side. It could be argued that forcing developers to pick a name for any concrete subclass, even empty ones, will result in code which better expresses their intent. I think, to be totally correct in terms of the paradigm, Object should be marked abstract, but when it comes down to it, there's no real benefit, it's a matter of design preference (pragmatism vs. purity).
Is the practice of using a plain Object for synchronisation a good enough reason for it to be concrete?
Many of the other answers talk about constructing a plain object to use in the synchronized() operation. While this may have been a common and accepted practice, I don't believe it would be a good enough reason to prevent Object being abstract if the designers wanted it to be. Other answers have mentioned how we would have to declare a single, empty subclass of Object any time we wanted to synchronise on a certain object, but this doesn't stand up - an empty subclass could have been provided in the SDK (java.lang.Lock or whatever), which could be constructed any time we wanted to synchronise. Doing this would have the added benefit of creating a stronger statement of intent.
Are there any other factors which could have been adversely affected by making Object abstract?
There are several areas, separate from a pure design standpoint, which may have influenced the choice. Unfortunately, I do not know enough about them to expand on them. However, it would not suprise me if any of these had an impact on the decision:
Performance
Security
Simplicity of implementation of the JVM
Could there be other reasons?
It's been mentioned that it may be in relation to reflection. However, reflection was introduced after Object was designed. So whether it affects reflection or not is moot - it's not the reason. The same for generics.
There's also the unforgettable point that java.lang.Object was designed by humans: they may have made a mistake, they may not have considered the question. There is no language without flaws, and this may be one of them, but if it is, it's hardly a big one. And I think I can safely say, without lack of ambition, that I'm very unlikely to be involved in designing a key part of such a widely used technology, especially one that's lasted 15(?) years and still going strong, so this shouldn't be considered a criticism.
Having said that, I would have made it abstract ;-p
Summary
Basically, as far as I see it, the answer to both questions "Why is java.lang.Object concrete?" or (if it were so) "Why is java.lang.Object abstract?" is... "Why not?".
Plain instances of java.lang.Object are typically used in locking/syncronization scenarios and that's accepted practice.
Also - what would be the reason for it to be abstract? Because it's not fully functional in its own right as an instance? Could it really do with some abstract members? Don't think so. So the argument for making it abstract in the first place is non-existent. So it isn't.
Take the classic hierarchy of animals, where you have an abstract class Animal, the reasoning to make the Animal class abstract is because an instance of Animal is effectively an 'invalid' -by lack of a better word- animal (even if all its methods provide a base implementation). With Object, that is simply not the case. There is no overwhelming case to make it abstract in the first place.
From everything I've read, it seems that Object does not need to be concrete, and in fact should have been abstract.
Not only is there no need for it to be concrete, but after some more reading I am convinced that Object not being abstract is in conflict with the basic inheritance model - we should not be allowing abstract subclasses of a concrete class, since subclasses should only add functionality.
Clearly this is not the case in Java, where we have abstract subclasses of Object.
I can think of several cases where instances of Object are useful:
Locking and synchronization, like you and other commenters mention. It is probably a code smell, but I have seen Object instances used this way all the time.
As Null Objects, because equals will always return false, except on the instance itself.
In test code, especially when testing collection classes. Sometimes it's easiest to fill a collection or array with dummy objects rather than nulls.
As the base instance for anonymous classes. For example:
Object o = new Object() {...code here...}
I think it probably should have been declared abstract, but once it is done and released it is very hard to undo without causing a lot of pain - see Java Language Spec 13.4.1:
"If a class that was not abstract is changed to be declared abstract, then preexisting binaries that attempt to create new instances of that class will throw either an InstantiationError at link time, or (if a reflective method is used) an InstantiationException at run time; such a change is therefore not recommended for widely distributed classes."
From time to time you need a plain Object that has no state of its own. Although such objects seem useless at first sight, they still have utility since each one has different identity. Tnis is useful in several scenarios, most important of which is locking: You want to coordinate two threads. In Java you do that by using an object that will be used as a lock. The object need not have any state its mere existence is enough for it to become a lock:
class MyThread extends Thread {
private Object lock;
public MyThread(Object l) { lock = l; }
public void run() {
doSomething();
synchronized(lock) {
doSomethingElse();
}
}
}
Object lock = new Object();
new MyThread(lock).start();
new MyThread(lock).start();
In this example we used a lock to prevent the two threads from concurrently executing doSomethingElse()
If Object were abstract and we needed a lock we'd have to subclass it without adding any method nor fields just so that we can instantiate lock.
Coming to think about it, here's a dual question to yours: Suppose Object were abstract, will it define any abstract methods? I guess the answer is No. In such circumstances there is not much value to defining the class as abstract.
I don't understand why most seem to believe that making a fully functional class, which implements all of its methods in a use full way abstract would be a good idea.
I would rather ask why make it abstract? Does it do something it shouldn't? is it missing some functionality it should have? Both those questions can be answered with no, it is a fully working class on its own, making it abstract just leads to people implementing empty classes.
public class UseableObject extends AbstractObject{}
UseableObject inherits from abstract Object and surprise it can be implemented, it does not add any functionality and its only reason to exist is to allow access to the methods exposed by Object.
Also I have to disagree with the use in "poor" synchronisation. Using private Objects to synchronize access is safer than using synchronize(this) and safer as well as easier to use than the Lock classes from java util concurrent.
Seems to me there's a simple question of practicality here. Making a class abstract takes away the programmer's ability to do something, namely, to instantiate it. There is nothing you can do with an abstract class that you cannot do with a concrete class. (Well, you can declare abstract functions in it, but in this case we have no need to have abstract functions.) So by making it concrete, you make it more flexible.
Of course if there was some active harm that was done by making it concrete, that "flexibility" would be a drawback. But I can't think of any active harm done by making Object instantiable. (Is "instantiable" a word? Whatever.) We could debate whether any given use that someone has made of a raw Object instance is a good idea. But even if you could convince me that every use that I have ever seen of a raw Object instance was a bad idea, that still wouldn't prove that there might not be good uses out there. So if it doesn't hurt anything, and it might help, even if we can't think of a way that it would actually help at the moment, why prohibit it?
I think all of the answers so far forget what it was like with Java 1.0. In Java 1.0, you could not make an anonymous class, so if you just wanted an object for some purpose (synchronization or a null placeholder) you would have to go declare a class for that purpose, and then a whole bunch of code would have these extra classes for this purpose. Much more straight forward to just allow direct instantiation of Object.
Sure, if you were designing Java today you might say that everyone should do:
Object NULL_OBJECT = new Object(){};
But that was not an option in 1.0.
I suspect the designers did not know in which way people may use an Object may be used in the future, and therefore didn't want to limit programmers by enforcing them to create an additional class where not necessary, eg for things like mutexes, keys etc.
It also means that it can be instantiated in an array. In the pre-1.5 days, this would allow you to have generic data structures. This could still be true on some platforms (I'm thinking J2ME, but I'm not sure)
Reasons why Object needs to be concrete.
reflection
see Object.getClass()
generic use (pre Java 5)
comparison/output
see Object.toString(), Object.equals(), Object.hashCode(), etc.
syncronization
see Object.wait(), Object.notify(), etc.
Even though a couple of areas have been replaced/deprecated, there was still a need for a concrete parent class to provide these features to every Java class.
The Object class is used in reflection so code can call methods on instances of indeterminate type, i.e. 'Object.class.getDeclaredMethods()'. If Object were to be Abstract then code that wanted to participate would have to implement all abstract methods before client code could use reflection on them.
According to Sun, An abstract class is a class that is declared abstract—it may or may not include abstract methods. Abstract classes cannot be instantiated, but they can be subclassed. This also means you can't call methods or access public fields of an abstract class.
Example of an abstract root class:
abstract public class AbstractBaseClass
{
public Class clazz;
public AbstractBaseClass(Class clazz)
{
super();
this.clazz = clazz;
}
}
A child of our AbstractBaseClass:
public class ReflectedClass extends AbstractBaseClass
{
public ReflectedClass()
{
super(this);
}
public static void main(String[] args)
{
ReflectedClass me = new ReflectedClass();
}
}
This will not compile because it's invalid to reference 'this' in a constructor unless its to call another constructor in the same class. I can get it to compile if I change it to:
public ReflectedClass()
{
super(ReflectedClass.class);
}
but that only works because ReflectedClass has a parent ("Object") which is 1) concrete and 2) has a field to store the type for its children.
A example more typical of reflection would be in a non-static member function:
public void foo()
{
Class localClass = AbstractBaseClass.clazz;
}
This fails unless you change the field 'clazz' to be static. For the class field of Object this wouldn't work because it is supposed to be instance specific. It would make no sense for Object to have a static class field.
Now, I did try the following change and it works but is a bit misleading. It still requires the base class to be extended to work.
public void genericPrint(AbstractBaseClass c)
{
Class localClass = c.clazz;
System.out.println("Class is: " + localClass);
}
public static void main(String[] args)
{
ReflectedClass me = new ReflectedClass();
ReflectedClass meTwo = new ReflectedClass();
me.genericPrint(meTwo);
}
Pre-Java5 generics (like with arrays) would have been impossible
Object[] array = new Object[100];
array[0] = me;
array[1] = meTwo;
Instances need to be constructed to serve as placeholders until the actual objects are received.
I suspect the short answer is that the collection classes lost type information in the days before Java generics. If a collection is not generic, then it must return a concrete Object (and be downcast at runtime to whatever type it was previously).
Since making a concrete class into an abstract class would break binary compatibility (as noted upthread), the concrete Object class was kept. I would like to point out that in no case was it created for the sole purpose of sychronization; dummy classes work just as well.
The design flaw is not including generics from the beginning. A lot of design criticism is aimed at that decision and its consequences. [oh, and the array subtyping rule.]
Its not abstract because whenever we create a new class it extends Object class then if it was abstract you need to implement all the methods of Object class which is overhead... There are already methods implemented in that class...