Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Came across this coding standard from Oracle:
Do not use a static array of strings.
What is the reason for this recommendation?
Arrays are mutable containers. Global mutable container without built-in synchronisation is multi-threaded horror waiting to happen. You can store reference to that array in some local context and then have it's content changed at any time without you knowing it. Or vice versa you may assume that this is convenient global state, but then every client must know the exact correct way to synchronise its access to that state. And somebody will forget and bug will be born.
I believe it's due to developers using String as a replacement (most likely unintentionally) for enumeration, and the static String[] was a way to group these types.
It could be targetting design flaws that were common at the time the article was written
For all we know, this article could be targetting the Java 4- code base.
Not saying this was written during Java 4, but that most production code existing at the time may have been written in Java 4. The lack of autoboxing pitfalls (which are quite common) and no mentions of generics (raw types) lead me to believe this.
Why would Oracle enforce such a cryptic principle?
I don't believe it has to do with global state, since I'm sure singletons would have been mentioned (being the pinnicle of global state).
I doubt concurrency is the issue, since the article does not mention anything else about sharing data across threads, or even using multiple threads. You would assume they would have mentioned SOMETHING about the thread environment.
Misusing String for type enumeration purposes was common back in the day, so I'm sure this statement (if related to what I think it is) was a lot easier to understand back then. I find it to be quite a stretch that this statement was just as cryptic back then, yet no one has cared to question it, resulting in the lack of google results when digging into this.
My Answer
Developers to this day still misuse String for type information. With the lack of enumeration, I could see how a developer may be tempted to do something along the lines of:
class Card {
static String HEARTS = "HEARTS";
static String DIAMONDS = "DIAMONDS";
static String CLUBS = "CLUBS";
static String SPADES = "SPADES";
static String[] CARD_TYPE = {
HEARTS, DIAMONDS, CLUBS, SPADES
};
private String type;
//...
}
Using the array for easy looping (as one would do with Enum.values()).
Using String as enums is frowned upon:
It's not type safe. If MAGE can be passed to a method, ANY String could be passed in it's place. This leads us to...
Mistakes are easier to make. It's possible for a typo to go unnoticed, which may seem small for the average developer, but could be catastrophic for businesses with large code bases and many consumers (such as Oracle). For example: a hidden typo results in a comparison returning false. This prevents a service from launching. The lack of this service results in a bug. If not found before users notice the bug, it could lead to exploits.
This could be fix by using Java's built-in type system:
abstract class CardType {
}
class Hearts extends CardType {
}
....
Or
enum CardType {
HEARTS, DIAMONDS, ...;
}
Not only is this less error-prone, but it allows you to use polymorphism, which prevents the need to check the value in order to trigger a specific behavior. The behavior can be contained in the type itself.
Although I can't promise this is the correct answer, it seems to be the only answer that does not depend on the use of modifiers that weren't mentioned in the statement.
Yes, the example above does not use proper constants (lacks the final). But although constants should be preferred, they are not required to benefit from this design (being able to use String for type information) nor does the design require it to work . Since people may not have always used constants for this, they could have left out the final or "array of constants" for this purpose.
This way undermines the object oriented paradigm. Moreover it's a security hole, because the final keyword assures only reference value and leaves the content to be changed easily.
Some of them are arbitrary. For example, having a single return statement is a matter of style (maybe related to some analysis tool that in the past couldn't handle multiple return paths?).
Some of them are outdated. Like the one about StringBuilding.
I'd assume that these are a mixture of old performance recommendations and style guides. I'd reckon the String static array one falls in the latter category, with maybe a hint towards what others have said about the possible link with the introduction of enums (maybe that's why Strings in particular).
Some of them are actually completely unfeasible when you try to apply them to modern frameworks: "Do not use a switch to make a call based on the object type.", for example, is at the core of Akka Java (onReceive) method and in general in any type of pattern matching in Java...
While I admit it's curious, I'd say it's probably something related to some specific tool they used in the past or to the enum possibility mentioned. But it's just my opinion, not a definitive answer.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I'd like to have Java constant strings at one place and use them across whole project?I am confusing Is it a good practice for better readability or not?
Simple: when multiple classes need the same information, then that information should have a single "root".
So yes: it is absolutely good practice to avoid re-declaring the same value in different places. Having a "global" constant simply helps with avoiding code duplication - thus preventing errors later on, when you might have to change such values.
One single class with (unrelated) constants has problems. It is a bottleneck:
if in a team a constant is added at the bottom, someone else adding a constant will receive a VCS conflict. Enforce the declarations to be sorted alphabetically. It also ties this package together in other forms. Still many unneeded recompilations would be needed (see also the remark at the end).
In java 9 with modules, you would in every using module need to require the constants classes module, probably causing an unnecessary module graph.
Then there are constants which need not be named and still are not "magic".
In annotations as arguments. An annotation scanning can gather those values if you need uniqueness or such.
And finally there are shared constants. Near the used constructs is still my favourite.
Also the constants class pattern tends to be used often with String constants. That reeks of code smell, as it is a kind of burocracy where one
should use automatic mechanisms, OO, fixed conventions, declarative data.
For database tables and columns there exist better mechanisms.
Classes with constants (still) have the technical compilation problem that in java the constant is incorporated in the .class file itself, and the import disappears. Hence changing the original constant will not notify the compiler to recompile the "using" class. One needs a full clean build after recompiling a constants class.
If you think that your Strings are going to be referenced in many flows, then it is good to use. Moreover, it is a widely accepted practice as well.
It is good to create Interface & declare your all constant in it.
E.G
public interface ICommonConstants {
public static final String ENCODING_TYPE_UTF8="UTF-8";
}
Implement this interface in your all class where you like to use constants.You can use by calling
ICommonConstants.ENCODING_TYPE_UTF8
Code duplication is a code smell and if you wouldn't use readily available constants you need to re-declare the String over and over again for each class using it, which is bad.
This leads to less maintainable code, because when the duplicated String needs to change and you forget to update it in one of the classes, the code breaks.
It's common practice to set up a class holding reusable constants:
public final class MyDefs {
public static final String A = "a";
public static final String B = "b";
private MyDefs() {
// Utility class, don't initialize.
}
}
I would recommend an Enum, or you could just have sort of like a utility class with just static final strings. All depends on what you want do i guess, i don't see anything bad. if the class is going to be shared by many classes, that's fine.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I'm looking for the best way to implement three-valued logic.
I googled and found three different approaches:
Use null value for Boolean variable as undefined
This variant looks to dangerous for me because it can unexpectedly cause NullPointerException
Use Optional<Boolean> type
This variant still is a bit dangerous. To avoid NoSuchElementException you should use constructions like this:
Optional<Boolean> amIRight = Optional.empty();
if (Optional.of(true).equals(amIRight ) {
doSome();
}
It looks too wordy for me
Implement your own enum
The last variant seems to be the best. Almost safe, very simple in undefstanding. But I haven't find any of such enums in widely spread java libriaries such as Apache, Google Guava and so on. It looks strange for me everybody avoids the simpler and safest implementation.
May be I missed something and there are serious reason not to implement three-valued logic enum.
If enum works for you, go for it.
Don't use that Boolean, it is ugly and destroy readability ... I also can't imagine how horrible it would be if you want it to support 4 values later...
Other cautions / advise :
Are you sure that you will use only 3 values?
In many situation, design tends to change, and enum will be no longer enough.
Using a class that encapsulate enum (or int) can provide better flexibility.
However, you can change from enum to class later.
In my program, I extensively use enum.
You shouldn't care much about what popular libraries do, just pick the best that work for you!
About the very interesting hypothesis :
... there are serious reason not to implement three-valued logic enum. ...
Suppose that I am Java language designer.
You ask for a 3-logic enum.
I accept you proposal.
Then, Mr.2D ask "We have 3-logic enum. Why don't you provide 4-logic enum to support +x -x +y -y?".
I give him what he want.
After that, Mr.LoveFive Mr.ObsessiveSick ..... I think you got the point.
There has to be a threshold (when to stop) and the demand for 3-enum is relatively very low compared to 2-enum (boolean).
I agree that enums is by far the safest and best solution to your problem. Perhaps enums are not widely used in projects like Apache because enums are relatively new in Java (I think they came along in Java 1.5).
If you want 3 valued logic, you are no longer talking about simple true/false conditions, you are talking about a state machine. Arguably state machines are among the most powerful paradigms in programming. If you aren't conversant with automata theory, look it up.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I've seen some legacy code that uses lengthproperty on some objects and others that uses length() method. Currently I'm working with a NodeList from the org.w3c.dom package and I found that it have the getLength() method to get the numbers of elements.
My Question is how as Java developer I can know how to determine when to use length, length(), size(), getLength()? obviously it depends of the object type and the API is there for read... but the point is how the Java Development select which of that implements in their classes.
Note: In the Question When to use .length vs .length() Makoto answer's indicates that .length is a property on arrays. That isn't a method call, and length() is a method call on String. But, why is the reason? why not use ever a method or ever a property for maintain the consistency around all the API.
how would Java developers select which of [the methods] to implement in their classes?
When you implement classes that contain other objects, it's almost always going to be size(), the method provided by theCollection interface.
As far as other choices go, you should avoid exposing member variables, even final ones, because they cannot be accessed through an interface. Java gets away with it for arrays because of some JVM trickery, but you cannot do the same. Hence, length should be out: it remains in Java because it's not possible to change something that fundamental that has been in the language from day one, but it's definitely not something one should consider when designing new classes.
When you implement your own type that has length (say, a rectangle or a line segment) you should prefer getLength() to length() because of Java Beans naming conventions.
obviously it depends of the object type and the API is there for read...
You already have answered your question yourself: look in the API documentation of whatever class you are using.
but the point is how the Java Development select which of that implements in their classes.
The classes in Java's standard library have been developed over a long period of time by different people, which do not always make the same choice for the name of methods, so there are inconsistencies and unfortunately you'll just have to live with that.
There is no clear rule, otherwise we wouldn't see such a mixup in the jdk itself. But here are some things to consider when making such a design decision.
Don't worry to much. It is a minor thing and won't make to much of a difference. So when you think longer then 5 minutes about this, you are probably wasting money already.
Use getters when a frameworks need them. Many frameworks depend on the getter style. If you need or want such frameworks to work nicely with your class it might be beneficial to use that style.
Shorter is better. the 'get' part doesn't increase clarity. It just generates to characters of noise to the source code, so if you don't need it for some reason, don't use it.
Methods are easier to evolve. Length is often a quantity that is not set directly but somehow computed. If you hide that behind a method it gives you the flexibility to change that implementation later on, without changing the API.
Direct field accesses should be a tiny bit faster, but if you aren't working on high volume online trading or something, the difference isn't even worth thinking about. And if you do you should do your own measurements before making a decision. The hotspot compiler will almost for sure inline the method call anyways.
So if there aren't any external forces driving you in a different direction I would go with 'length()'
According to OOPS principles, length should be attribute and getLength() should be method. Also length attribute should be encapsulated should be exposed through methods, so getLength() sounds more appropriate.
Unfortunately not all Java library classes follow standards. There are some exceptions and this is one among them.
In a pure OO language it should be probably always a method like length(). So in a class hierarchy you can override the attribute length.
But Java is not pure OO. And the main reason for fields (.length) vs method (length()) is/was performance issues.
And even Sun/Oracle programmers did some bad class design.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Is it considered bad style to use long, but descriptive method names such as "adjacentLocationsByState()" and if so, would it be better to shorten it to something like "adjLocByState" which is definitely shorter, but also less readable in my opinion
Don't make me think.
When I read your code, if I have to stop and think about what the method name might mean, it usually means that the method name is wrong. Longer method names are preferable when it adds useful context to the method.
There are two rules I basically follow when writing code:
Must be readable as a normal text to which a human eye got used from books and mass media (so adjLocByState is not the case)
Maximize brevity, utilize programming techniques - code conventions and default states. These could be applied when some of the terms start appear to repeat too often.
So, adjacentLocationsByState() reads perfectly fine, but it could be shortened to just:
adjacentLocations()
which by default would return locations by their state and adjacentLocations(STATE) or chaining with fluent interface technique which allows more options for having the criteria: adjacentLocations().by(STATE). STATE here is a member of an enum LocationCriteria.
So in the end of the day it could look like:
adjacentLocations()
adjacentLocations().by(STATE)
adjacentLocations(STATE)
Of course, there is a time sacrifice which is spent on coding the 2nd and the 3rd forms.
Longer version is more readable and the the code is self documenting. So a good method name = method responsibility. Adj can be understand as adjust or adjacent, etc.
Keep in mind: Code is read 10 times more than it is written.!
You really write code that will often be read again and again. The more meaningful your names are, the more understandable is the code.
You are declaring classes, fields, methods, variables, and many more. You are thinking about them, you are developping a well-defined structure. All the time, you make hard decisions. The names that you give to your entities (classes, fields, ...) reflect all your thoughts on that. They reflect the intention of your code.
Conclusion: Names are the most important properties of your code. So, you always should think deeply about the names you give to your variables, methods, and so on. And you always should not abbreviate them in what way ever.
Its part of Documentation.
Usually everybody like to write Code in two phases before commit:
Implementation
Documentation
By example (phase 1):
ObjectOutputStream oos = ...
List a : ob.getSOE();
for(Object a: b){
oos.writeObject(a);
}
Then phase 2:
ObjectOutputStream stackOverflowElementOuputStream = ...
List stackOverflowElements : ob.getStackOverflowElement();
for(Object currentStackOverflowElement: stackOverflowElements){
stackOverflowElementOuputStream.writeObject(currentStackOverflowElement);
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Sorry for posting a rather vague question here - but I've been struggling to find a definitive answer to this one - maybe there is none, but just thought asking fellow developers.
Last week, a colleague of mine mentioned that the length of constructors (In Java and in OOP in general) should be kept to a minimum. While I do agree the approach in general, he went on to say that it should be only a few lines - 3-4 lines at maximum.
I'm not sure how he arrived at this number and I wonder how useful that approach is. If you have some complex initialisation to perform, your constructors will exceed that limit.
You can split and break and refactor your code into smaller functions till cows come home, I prefer to keep related code into one method and avoid un-necessary functions as it makes code more readable.
This at times does lead to situations where constructors are fairly moderate in size - 50-100 lines of code in worst scenarios, but then even if I break it up into functions, technically speaking, that code is still "called as part of initialisation". So, 100 lines of code might be replaced by a single function call, but that 100 lines still get called when you call the function?
I also looked at checks type default definitions and it has default constructor length set to 150, which sounds more reasonable "Than a few lines code".
Would love to know what you guys follow as rule of thumb or if there is, indeed, such a accepted upon limit.
Good rule of thumb is that any method (or constructor) should fit on one screen in your IDE so you don't have to scroll down when you are trying to read and understand what is this method doing (so it improves readability).
Nothing prevents you from making exception from time to time but you should generally split really long methods to smaller chunks because I've really seen methods few hundred lines long and it really made me cry when I had to change the code.
This is just a common practice but not anything. I have made classes that had a lot of code in constructors. I also had classes with no constructor. As mentioned above, there is no such thing that you should not contain a lot of code in constructors, and JVM loads them too.
So why this concept came up? It is because people think that constructors are for initializing variables in objects since they are called only when new instances are created. Also doing a lot of work in the constructors makes no point in using OOP principles. OOP itself means 'Object Oriented Programming' which is meant to structure code as objects. So I'm leaving the conclusion to you. See the both examples and think which one is better.
Example 1:
public Dog(String name)
{
System.out.println("Dog " + name + ": Bark!Bark!");
}
Example 2:
public Dog(String name)
{
this.name = name;
}
public void bark()
{
System.out.println("Dog " + name + ": Bark!Bark!");
}
In the first example, the dog barks only once, but in the second example, you can make the dog bark as many times as you want. And for this same reason, they say to use constructors only for initializing values.
Hope this helps.
I've been struggling to find a definitive answer to this one - maybe there is none
You are right. There isn't a definitive answer. It is subjective.
Would love to know what you guys follow as rule of thumb ...
I don't. I use my judgement on a case-by-case basis. Subjectively.
... or if there is, indeed, such a accepted upon limit.
There isn't. You won't find any specified limits in the main-stream Java coding standards. A decent coding standard won't be prescriptive about this because it is counter-productive.
On the other hand, this is the kind of situation where code reviews can be beneficial. If you see an "overly long" constructor or method, it is worth pointing out, especially if there is a good refactoring available; i.e. one that your colleagues would agree improves readability.