import static vs. static final - java

In the past I often used "import static" construct in Java classes. Recently I realized that instead of
import static my.pack.A.MY_CONSTANT;
you can use
import my.pack.A;
public class B {
private static final MY_CONSTANT = A.MY_CONSTANT;
}
The most obvious advantages of this approach are:
You can use refactoring in Eclipse to easily strip out all long constant expressions like A.B.C.CONSTANT.ANOTHER_ONE.TOO_LONG from your code without messing with static imports (which are not so quick to master in Eclipse)
You can give any name to any expression, which may be more meaningful in the current context.
For example:
private static final PAYMENT_TYPE = PaymentType.CASH;
...
calculateSomething(amount, PAYMENT_TYPE);
instead of
import static my.pack.PaymentType.CASH
...
calculateSomething(amount, CASH);
and also this is more easy to refactor, if the default PaymentType value changes to CREDIT_CARD.
My question is: are there any downsides of this approach compared to static imports or can it be used everywhere instead?
My only concern for now is the resulting compiled .class file, which is probably different for the two described approaches. So performance and memory usage may theoretically suffer.

I think the only downside is you have more code where you assign one constant to another constant. Other than that there should be no difference. Performance and memory shouldn't matter, you'll likely have more references back to the same constant pool entries. Even if it created separate constant pool entries it would take a lot of them to make a difference.
Being able to give good names to constants might be a very good thing, in cases where it isn't feasible to rename the original entries.

It is mostly a matter of taste, but the official docs recommend using the static version sparingly, especially with a wildcard. The main downside of static import is that it pollutes your namespace by added all the static members to it. In your above example, it should be about what you think it more readable for your code. Resist the urge to do "import package.*" unless you really want all the static members of package.
It should not effect your compiled code -- it is merely provides a shorthand access to the same constant.

Related

Can I call a static method of another class without using the class name?

Can I call a static method of another class without using the class name (in the same package)? There are similar questions but all answers there use class names.
Yes. But, you would need to import it. Specifically, import static. Like,
import static com.package.OtherClass.someMethod;
Then you can call someMethod(String) like
someMethod("Like that");
It is possible using static imports, however I would like to caution you against using them. Static imports obfuscate where the code lives which makes it harder to understand the code structure. Combined with * imports, humans can no longer determine (without spending a lot of time) the source of the method, although IDEs can.
An example of why it could be bad: let's say you want to see how a problem was solved in a open source project, to get ideas for your own project. And you know what? You can view the code as HTML online. Things are going great! You view the java file you want to see. Then there is this peculiar method "foo". So you search the page for "foo" and there is exactly 1 match (the one you are looking at). There are multiple import static blabla.* lines at top, so that is a dead end. You download the source. Next you do a full text search on the entire project for "foo(" => 5000 matches in 931 files. At which point you no longer have a choice other than loading the project into an IDE if you want to grok the code. You would not have to do any of that if the author would have made it clear where the method lives to begin with. Now, if you do not use * imports, then finding the class is a 2 step process, so it is not nearly as bad. I personally don't use static imports at all. With short yet meaningful names, I find that the explicit type is preferable.
I dislike static imports, because it breaks OO (well, not technically, just conceptually). But this is a personal opinion and the vast majority disagrees with me. So feel free to form your own. The following post has a great discussion on when (not) to use static imports:
What is a good use case for static import of methods?
Yes it's possible to call static method of a class without using Class reference by using static import.
ex:
import static java.lang.Math.*;
public class compute{
public double getSqrt(double n){
return sqrt(n)
}
}
It's preferable to use this way if static methods are used in lot of places in the class.

Static Import file or static import individual items

Whether I am right or wrong about this I am not sure but SonarLint gives me countless warnings about the repeated use of certain strings.
As a result, I created a constants file purely for Strings in a module that is already accessed in every other module in the project.
My thought was if we are continually being warned about this. It's probably creating each of these strings multiple times and temporarily increasing memory.
(It's a web app, generating JSON and XML with many frequently repeated terms such as "identity" or "community")
The question I am wondering is, my IDE (IntelliJ) seems to just keep adding the following line:
import static com.*****.*****.resources.Constants.*
Instead of:
import static com.*****.*****.resources.Constants.PARAM_NAME_HASEMAIL;
import static com.*****.*****.resources.Constants.PARAM_NAME_HASSMS;
import static com.*****.*****.resources.Constants.PARAM_NAME_CMD;
Bearing in mind the file is currently small with maybe around 100 constants, but that figure will eventually reach 250.
First of all my question is, which of the imports is more efficient, just import the file, import each required constant, or it doesn't matter that much (max will definitely be 250 constants in the file)
The second question I have is, is this worth the effort (easy but grunt work)?
One example is:
data.has(PARAM_NAME_OPTIN)
data.remove(PARAM_NAME_OPTIN);
data.put(PARAM_NAME_OPTINTYPE, Coupon.OPTIN_MODE_SINGLE_OPTIN);
The above is in maybe 3 or 4 locations in different files.
The definitions of those 2 constants are:
public static final String PARAM_NAME_OPTIN = "optin";
public static final String PARAM_NAME_OPTINTYPE = "optInType";
The worst offender is below. It is in every single method that makes a call to the backend from the front end (following an ajax request in the browser):
json.put(PARAM_NAME_CMD, "Coupon.doSearchCouponEntriesByCoupon");
json.put(PARAM_NAME_APPID, PARAM_NAME_CAMPAIGN);
json.put(PARAM_NAME_COMMUNITYID, session.getAttribute(PARAM_NAME_COMMUNITYID));
json.put(PARAM_NAME_IDENTITYID, session.getAttribute(PARAM_NAME_IDENTITYID));
Again the definitions are:
public static final String PARAM_NAME_APPID = "applicationId";
public static final String PARAM_NAME_CMD = "command";
public static final String PARAM_NAME_CAMPAIGN = "*****campaign";
public static final String PARAM_NAME_COMMUNITYID = "communityId";
public static final String PARAM_NAME_IDENTITYID = "identityId";
I have starred the package names to try to obscure the company. Even if this doesn't really share any IP or secrets, better safe than sorry.
I appreciate any feedback you give (good or bad).
Additional info: one of the files I am doing the import manually for each one used currently has 22 imports for those constants.
I guess if the number reaches such heights, then maybe I should switch to the * instead? Or does it still have memory implications?
My thought was, if we are continually being warned about this. It's probably creating each of these strings multiple times and temporarily increasing memory. (It's a web app, generating JSON and XML with many frequently repeated terms such as "identityId" or "communityId")
That's actually wrong. At runtime, all string literals are interned by the class loader. So, if you have 20 examples of "identityId" in many different classes, at runtime you will have only one String object that represents all copies of the literal. (This is NOT an implementation detail. The JLS guarantees this behavior.)
The real reason for the SonarLint warnings is that having multiple copies of the same string literal is liable to cause maintenance problems. If you want to change "identityId" to "identityID", you have 20 separate places to change it ... and the IDE is not going to be a lot of help.
First of all my question is, which of the imports is more efficient, just import the file, import each required constant, or it doesn't matter that much
It has zero impact on runtime performance, and the impact on compilation speeds is most likely insignificant.
The most significant impact of the different styles of import is on the readability of your source code, and that is largely a matter of opinion.
The second question I have is, is this worth the effort?
That is definitely a matter of opinion .... in the examples that you presented.
However, if the strings were messages for users to read, then you may need to internationalize them. If that is the case, then you will be better of storing the strings in (for example) a properties file ... and use different files depending on the user's preferred language.
Finally, assuming that you do decide to use String constants (which is a good idea), I wouldn't recommend putting them all into a big "constants" class. Define them in ordinary classes and interfaces, according to their purpose.
Repeated use of the same literal string does not create a memory overhead, since all literal strings in Java source code are interned. SonarLint warns you not because of memory inefficiency, but because of the risk of errors and reduced readability.
The problem with your proposed solution using static import of the whole class, is that you won't know where the constants came from when you later read the source code where they are used. That's why it's generally preferred to "static import" named fields. But if you have 250 such constants, you might not want to add 250 static import lines to your file.
Instead of naming your constants PARAM_NAME_APPID etc., put them in a class called ParamNames. Then you "static import" the class name so you can see where it's come from, and the constants have self-explanatory names:
static import package.name.ParamNames;
....
xxx = ParamNames.APP_ID;
Refactor the Constants class into a property file.
It then contains your constants like this
PARAM_NAME_APPID=applicationId
you can load it using
Properties constants = new Properties();
try (FileReader reader = new FileReader("constants.properties")) {
constants.load(reader);
}

Is it OK to create a Constants class with large number of static fields?

Let's say I have a constants class containing 200+ static fields :
class AnimalConstants {
static final int AARDVARK = 1;
static final int ANTELOPE = 2;
static final int BEAR = 3;
...
...
static final int ZEBRA = 200;
}
Can anyone explain if there are any negative impact on performance and memory from using such classes.
Would it be better or worse if the class is changed to an interface (e.g. SwingConstants) and being implemented by some classes?
Would it be better or worse if I implement the constants as an Enum class?
I don't think the impact is performance or memory.
I think it has to do with things like readability of code, keeping constants close to where they're used, and fundamental understanding of your problem.
I prefer to declare constants closer to where they're used. I believe they're easier to understand that way.
I would be surprised if the real constants that you claim number 200+ are truly related. If they are, they belong together in one place. If not, I'd say that they should be broken into smaller pieces and declared closer to where they're used.
I'll bet there's more context than your contrived example that would change responses if known.
Sure , enums are great. But see my other comments first.
Of course enum implementation is more ponderous than bunch of int constants but using enum:
you don't need to hardcode actual values of Animals (in your case) that can change later
you don't need to hardcode total number of Animals and you can simply iterate through all animals
methods with parameter of this enum will be understood correctly (foo(Animal animal) is better than foo(int animal))
you can add additional functionality to your enum values later, e.g. internal value isMammal
Would it be better or worse if the class is changed to an interface (e.g. SwingConstants) and being implemented by some classes?
--> That would be a Constant Interface Pattern. If we use interfaces for constant and it is implemented by all classes but if you are developing an API, it is something like you are exposing your implementation details. Above wiki link explains this very well.
In both approach(Interface or Class) I would suggest using final class, create constants and do static import for constants wherever necessary.
Would it be better or worse if I implement the constants as an Enum class?
--> With Enums, this would be the best approach.
Changing any value that has already been compiled into another class may require a full build.
Addendum: See Is it possible to disable javac's inlining of static final variables? for a more thorough examination.
Yes it is okay to create a large number of constants. It is hard to discuss negative impact because we don't know any alternatives because we don't have your functional requirements.
But be assured that the compiler is written to work well with code written by humans. Having a bunch of fields is probably going to be okay.
I feel that constants can be very nice as it can be used in switch case since JDK7, you can compare with == and the variable name can be informative.
Can enum be even better? Yes it can. Explore the features of enums and see if anything is appealing to you
For your kind of vars (Animal Types) i suggest you to use an Enumerator instead of a class. With the number of vars using it shouldn't be a problem for performance as you're only using int primitive. The problem would have occurred if any var has been a class, that are more memory demanding to maintain their structure. I hope to have clarified your doubt (Sorry for the poor english, i'm a little rusted)

Ideal way to organize Java constants

We have a huge projects based on an old jdk 1.4. We have migrated the web app to JDK 1.6 but still lot of inefficient practices and bad design exist in the code.
On of the major pain point huge java classes 2500+ lines of code in single java file. So many files like these.
In an attempt to refactor the classes I had started off by removing constants and putting constants in different Constants.java file. but since there are so many constants through-out the application, the constants file has the risk of growing to humongous proportions.
I would appreciate feedback on what strategy are developers adopting to keep code clean and maintainable.
Keep your constants in the class they are related to, don't feel obligated to extract them. It may clean up the code of the class, but mixing unrelated constants in a file is not an improvement.
Keep things related together.
And also you can convert them to Enums when possible/useful (but that can require some refactoring).
Putting all the Constants in a single file is a terrible idea! Especially the uber-Constant anti-pattern where all the Constants are in an Interface that every class has to implement. 10 ways to Sunday terrible! This was a bad idea when people started doing it back in the early 1990's before Java! It is definitely a bad idea in 2012!
It means you are mingling lots of un-related information and creating un-needed dependencies everytime you import this uber-Constants file. Things that go together should be together in an Enum or at least in the Class that uses them as arguments to its methods so that when they are changed you know how to do an impact analysis easily.
Imagine Color constants mixed in with DaysOfTheWeek constants mixed in with other business domain constants and there will be hundreds if not thousands of these things in a single file. How can that ever be considered a good idea? In every non-contrived case, an Enum that is a public inner member of a Class is a better solution.
It also means you have a single flat namespace to try and create names that don't conflict, then they aren't obvious what they belong to and how they should be used. This is never a positive exercise.
When designing and refactoring you should always:
Strive for high cohesion, this means keep related things as close together as possible.
Strive for loose coupling this means don't let un-related things leak into other un-related scopes.
Strive for self-documenting maintainable code, dozens or hundreds of private static final String/int declarations all mixed together doesn't fit this definition by anyone's standard!
In 2012 C-style constants are a poor solution when you now have Enum as a tool, you should be focused on converting as many of these groups of Constants to Enum wherever possible. Enum is type safe and can have other attributes and properties and behaviors attached to it to make them intelligent. That is the path to go down.
Just putting constants in a Constant.java file doesn't make sens in my opinion (it just move the problem away). But sometimes I use to regroup them to clear the things and use several files to regroup them : DatabaseConstants.java, GraphicConstants.java and so on...
and of course, using enums can be useful too (and best practice).
edit : to be precise, I actually work with Java ME application, so it's just a way to "mimic" the enums I can't have, with a "controlled vocabulary" in abstract classes (I miss all the Java EE features...)
For someone who is visiting this page.
If you don't want to maintain multiple constant files, below is the better way to organize.
public interface Constants {
public static final String CREATE_USER = "createUser";
// Nested Interface.
public interface ProjectConstants {
public static final String CREATE_PROJECT = "createProject";
public static final String INVALID_SESSION = "Invalid Session";
// As you know they are implicity public static final.
}
}// Accessed as:
Constants.ProjectConstants.CREATE_PROJECT
Updates:
As a best practice, its better to use Class.(See comments. . Thanks keplerian.)
public final class Constants {
private Constants() {
// restrict instantiation
}
public static final double PI = 3.14159;
public static final double PLANCK_CONSTANT = 6.62606896e-34;
}
import static Constants.PLANCK_CONSTANT;
import static Constants.PI;
public class Calculations {
public double getReducedPlanckConstant() {
return PLANCK_CONSTANT / (2 * PI);
}
}
I'd like to share a design pattern for constants i've seen a few years ago that maybe can help.
Start by creating a BaseConstant file. This will hold all your global constants that all packages could use.
Now in each subpackage of your app create a Constants file that will only be related to the subpackage . So if you had . a subpackage called Login only put constants related to login there. But the key is to extend off of BaseConstants. this way you get to see all the global constants in the IDE chooser but when you open the file you only see your package constants. that being said i think constant files can get really heavy and duplicate values and hard to read.
Here is what i mean ..
public class BaseConstants{
public static final String GLOBAL1= "GLOBAL string";
public static final String GLOBAL2= "another GLOBAL string";
}
Now in all your other packages create a files like this:
class MyPackageConstants extends BaseConstants{
public static final String LOCAL1 = "local String"
public static final String LOCAL2= "ANOTHER LOCAL string";
}
in your IDE when you type "MyPackageConstants." you should see all the constants for the entire application.
I've never heard of putting all of the constants to a single java file. The best way is to put the constants accossiated with the classes in themselves, but name them with capital letter and underscores like this one: EXAMPLE_CONSTANT
Have you tried using Enums for all of your constants? I've been told it is the preferred way since Java 1.5.
http://docs.oracle.com/javase/1.5.0/docs/guide/language/enums.html
I think that if you have multiple java files over 2500 LOCs, the decision where to put the constants should be the least of your problems. You should form a clear picture of how the restructured system will look like.
This is probably much harder then deciding where to stick the constants and other syntactic considerations but needs to be done first nevertheless.

Always Use Final?

I have read that making something final and then using it in a loop will bring better performance, but is it good for everything? I have lots of places where there isnt a loop but I add final to the local variables. Does it make it slower or is it still good?
Also there are some places where I have a global variable final (e.g. android paint), does it mean I don't have to make it a local final when using it in loops?
The first thing you should consider is; What is the simplest and clearest way I can write this code. Often this performs well.
final local variables is unlikely to affect performance much. They can help clarity when you have long methods, but I would suggest breaking up method is a better approach.
final fields can affect performance to small degree, but a better reason to make it final is to make it clear that this field never changes (which also helps the JIT)
Don't think about performance. final on object member (fields) have significant memory semantics that may improve performance (but more importantly, its often necessary to make the code correctly work at all). You should always put final on object members whenever you can. For local variables however, you should only use it if it will improve code readerability, or can prevent bugs when a maintainer touches your code.
The general consensus of the Java community is that final on every local variables will make the code difficult to read. On the performance front, you can expect no optimization as local variables are easy to analyze for the compiler. In other words, the compiler can figure it out by itself.
From my experience most variables could be declared final.
However, it looks very ugly. That is my main point against it.
And if the part of the program is not performance critical, beware of premature optimization.
It's considered good form to use final where possible (for fields and variables, not classes and methods), if for no other reason than it makes testing easier. Final will never have a negative impact on performance.
Here are my 2 cents:
Use final on attributes to minimize mutability and for documentation purposes, only use final on local variables if they are used in inner/anonymous classes.
DON'T use it for microoptimizations! Especially don't use them on classes or methods because you think it will improve performance. Make classes and methods final to prohibit inheritance or overriding methods.
Final on attributes should not have any impact on performance. Except: in a multi threaded environment where several threads access the same field and "don't know" if they have to relaod it. Final on local variables has no impact at all, as nothing except the local scope can access them anyway.
Final on methods can have an impact during JIT compiling. If a method is final and small the compiler can inline it in loops, as it is clear that no one will have overwritten it.
I usually don't use final on attributes at all, as final attributes can not be loaded from DBs easily etc. Declaring pararameters to methods final lokos ugly (I never assign to them inside my code anyway) but might prevent simple bugs comming from typoes. However if you start using proper names for your variables you unliek make such typoes.
Theoretically, if you make a local variable final it can be optimized. I don't think making them final yourself really improves performance though, because the optimizer probably already detects when your locals don't change. That said, it can't hurt to help it a bit.
In some situations, it would help to change one variable into two, e.g. from this
String a = "foo";
if (lol) a += "bar";
for(.. 1000 ...) doSomething(a);
to
final String a;
{
String ma = "foo";
if (lol) ma += "bar";
a = ma;
}
for(.. 1000 ...) doSomething(a);
Disclaimer: I'm not a JIT expert.
Final variables are constants, therefore the compiler could generate constant value instead of variable referencing instruction. Of course that would improve speed (and commonly size as well).
Also there are some places where I have a global variable final (e.g. android paint), does it mean I don't have to make it a local final when using it in loops?
Sorry, do you mean you don't have to:
final int somefinalvalue = 0;
void amethod() {
final int somefinalvalue = 0; // repeated from global one
}
or what? remember that if you declare local variable which has the same name as global one, that would 'shadow' the global one. i.e. it's actually a totally different variable. if you already have the global one, just use that. no need to re-declare.
I don't think this should be your first concern, as mentioned by #perter-lawrey. First, compiler optimization can very much do the trick; second, there are some tools that can analyze your generated class files and do the same thing, for example, ProGuard: java shrinker, optimizer, obfuscator, and preverifier.

Categories