www.norvig.com/java-iaq.html
There are lots of Java FAQs around, but this is the only Java IAQ. There are a few Infrequently Asked Questions lists, including a satirical one on C . Q: The code in a finally clause will never fail to execute, right? But heres an example where the finally code will not execute, regardless of the value of the boolean choice : try if choice while true ;
Anytime you define a equals method, you should also define a hashCode method. You must make sure that two equal objects have the same hashCode, and if you want better hashtable performance, you should try to make most non-equal objects have different hashCodes. Some classes cache the hash code in a private slot of an object, so that it need be computed only once.
The documentation in Hashtable talks about entries in the table, and the behavior of Properties is consistent if you assume that defauls are not entries in the table. If for some reason you thought defaults were entries as you might be led to believe by the behavior of getProperty then you will be confused. The previous two questions show that a programmer neeeds to be very careful when extending a class, and sometimes just in using a class that extends another class. Problems like these two lead John Ousterhout to say Implementation inheritance causes the same intertwining and brittleness that have been observed when goto statements are overused. As a result, OO systems often suffer from complexity and lack of reuse. Scripting , IEEE Computer, March 1998 and Edsger Dijkstra to allegedly say Object-oriented programming is an exceptionally bad idea which could only have originated in California.
You need to pay as much attention to the methods that you dont over-ride as the methods that you do. This is one of the big fallacies of Object-Oriented design using inheritance. Youre especially looking for trouble if the subclass changes the contract of any of the methods, or of the class as a whole. It is difficult to tell when a contract is changed, since contracts are informal there is a formal part in the type signature, but the rest appears only in comments. In the Properties example, it is not clear if a contract is being broken, because it is not clear if the defaults are to be considered entries in the table or not. Delegation means that you include an instance of another class as an instance variable, and forward messages to the instance. It is often safer than inheritance because it forces you to think about each message you forward, because the instance is of a known class, rather than a new class, and because it doesnt force you to accept all the methods of the super class: you can provide only the methods that really make sense. On the other hand, it makes you write more code, and it is harder to re-use because it is not a subclass. For the HashtableWithPlurals example, delegation would give you this note: as of JDK 12, Dictionary is considered obsolete;
The Properties example, if you wanted to enforce the interpretation that default values are entries, would be better done with delegation. Because the Java implementation team was rushed, and took the course that required writing less code. Global variables are considered bad form for a variety of reasons: Adding state variables breaks referential transparency you no longer can understand a statement or expression on its own: you need to understand it in the context of the settings of the global variables. State variables lessen the cohesion of a program: you need to know more to understand how something works. A major point of Object-Oriented programming is to break up global state into more easily understood collections of local state. When you add one variable, you limit the use of your program to one instance. What you thought was global, someone else might think of as local: they may want to run two copies of your program at once. In each case, you need to decide two things: how many copies of this so-called global variable do I need? Here are some common solutions: If you really want only one copy per each time a user invokes Java by starting up a Java virtual machine, then you probably want a static instance variable. For example, you have a MainWindow class in your application, and you want to count the number of windows that the user has opened, and initiate the Really quit?
You could easily add an instance variable to the Browser class to hold the display stream or frame, but you havent passed the current instance of the browser down into the methods in the Cookie class. You dont want to change the signatures of many methods to pass the browser along. You cant use a static variable, because there might be multiple browsers running.
Peter van der Linden , author of Just Java , recommends against both of the last two practices in his FAQ . I agree with him that Math m null is a bad idea in most cases, but Im not convinced that the MyStaticMethods demonstrates very poor OOP style to use inheritance to obtain a trivial name abbreviation rather than to express a type hierarchy.
See an example of how I used this approach to what I thought was good effect. Second, it is rather presumptuous to say that this is very bad OOP style. You could make a case that it is bad Java style, but in languages with multiple inheritance, this idiom would be more acceptable. Another way of looking at it is that features of Java and any language necessarily involve trade-offs, and conflate many issues. I agree it is bad to use inheritance in such a way that you mislead the user into thinking that MyClass1 is inheriting behavior from MyStaticMethods , and it is bad to prohibit MyClass1 from extending whatever other class it really wants to extend. But in Java the class is also the unit of encapsulation, compilation mostly, and name scope. The MyStaticMethod approach scores negative points on the type hierarchy front, but positive points on the name scope front. If you say that the type hierarchy view is more important, I wont argue with you. But I will argue if you think of a class as doing only one thing, rather than many things at once, and if you think of style guides as absolute rather than as trade-offs.
There are at least three different meanings that null is commonly used to express: Uninitialized. For example, terminal nodes in a binary tree might be represented by a regular node with null child pointers. Note that this is subtly different from the previous case, although some people make the mistake of confusing the two cases. The difference is whether null is an acceptable tree node, or whether it is a signal to not treat the value as a tree node. Compare the following three implementations of binary tree nodes with an in-order print method: // null means not applicable // There is no empty tree.
This method is not foolproof, because a garbage collection could occur in the middle of the code you are instrumenting, throwing off the byte count. Also, if you are using a just-in-time compiler, some bytes may come from generating code. You might be surprised to find that an Object takes 16 bytes, or 4 words, in the Sun JDK VM. This breaks down as follows: There is a two-word header, where one word is a pointer to the objects class, and the other points to the instance variables. Even though Object has no instance variables, Java still allocates one word for the variables. Finally, there is a handle, which is another pointer to the two-word header. Sun says that this extra level of indirection makes garbage collection simpler. There have been high performance Lisp and Smalltalk garbage collectors that do not use the extra level for at least 15 years. I have heard but have not confirmed that the Microsoft JVM does not have the extra level of indirection. An empty new String takes 40 bytes, or 10 words: 3 words of pointer overhead, 3 words for the instance variables the start index, end index, and character array, and 4 words for the empty char array. Creating a substring of an existing string takes only 6 words, because the char array is shared. Putting an Integer key and Integer value into a Hashtable takes 64 bytes in addition to the four bytes that were pre-allocated in the Hashtabl...
|