Can anyone please explain me in which scenario we use static initial block?
You can use it as a "constructor" for static data in your class. For example, a common situation might be setting up a list of special words:
private static final Set<String> special = new HashSet<String>();
static {
special.add("Java");
special.add("C++");
...
}
These can then be used later to check if a string matches something interesting.
The most common scenario is loading some resources on class load, for example loading library for JNI
And another common one is when some of the code you need to use to create your statics throw exceptions.
Another example is java.lang.Object
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
...
I use them all the time to initialize lists and maps.
List<String> myList = new ArrayList<String>(){{
add("blah");
add("blah2");
}};
for(String s : myList){
System.out.println(s);
}
Related
I have a fairly simple Java related question. I need to somehow obtain the new object name within the constructor to add it to an array. How would I achieve this, if it's at all possible?
For help visualizing, here's what I need to happen.
TestExample example = new examplemain();
TestExample.element exelement = example.new element();
At this point, with the creation of the new button object, I have a constructor. The examplemain class has a function known as update. I need this update to run through every single object to update drawing elements associated with exelement. The most obvious way is to add it to an array, and then when example.update() is called, just run an array to update everything. Something like this WOULD achieve the effect I'm looking for, but only for exelement, which is no good.
element() {
TestExample.array[0]="exelement"
}
I found things like this.toString(), getName() or getClass(), but I couldn't find any meaningful way to apply it in the method I need. To reiterate, I need to be able to do something like TestExample.array[0].status=1.
Thanks in advance!
It is a bit difficult to understand what you are saying because your examples clearly don't do what you are saying. (For instance TestExample.array[0] = "exelement" is just saving a string, and you can't resolve that to a variable.)
In fact, I'm pretty sure that the variables are a red herring too1. What you actually need is something like this:
// Simplistic incorrect version ...
public class Element {
private static List<Element> allElements = new ArrayList<>();
public Element() {
...
allElements.add(this);
}
public void update() { ... }
public static void updateAll() {
for (Element e: allElements) {
e.update();
}
}
}
The above has a couple of problems. Firstly the use of static is liable to be a memory leak unless you either have a reliable way to clean out any elements that are no longer needed, or you use a reference type so that the GC can break the links. The second issue is that your example is apparently using an inner class.
So using an inner class, it might look like this:
public class Outer {
private List<Element> allElements = new ArrayList<>();
public class Element {
public Element() {
...
allElements.add(this);
}
public void update() { ... }
}
public void updateAll() {
for (Element e: allElements) {
e.update();
}
}
}
Now ... if the Outer instance becomes unreachable, so do any Element objects that are only reachable via allElements.
1 - But if the variables are critical, then I'm afraid you are out of luck. Java doesn't provide a way to either take the address of a variable, or use reflection to lookup a local variable. This is what #Louis Wasserman is saying in his answer.
Unfortunately, this is absolutely impossible. Not even reflection can find the name of a field still in the process of being initialized.
You must, for example, pass in a name into the constructor.
I'm having an issue with SonarQube while using public static variables, the problem is that SonarQube want that to be public static final, this variable is being filled in other parts of the code, it is "dynamically" (filled with environment variable) then is used in all other classes.
This is the arrayList variable
public static List<String> listPersons = new ArrayList<>();
Errors by Sonar:
1- Make this "public static listPersons" field final
2- Make listPersons a static final constant or non-public and provide accessors if needed
3- Make this member "protected"
What's the best approach to fix this problem?
Technically, you can have the (reference of) the variable final and still have its contents dynamically filled at some later point:
public static final List<String> listPersons = new ArrayList<>();
//...
public void initialize() {
List<String> contents = populateContentsFromEnvironmentVariable();
listPersons.addAll(contents);
}
However, using a "mutable-content" constant such as this one introduces possible problems. For example, you need to make sure that client code doesn't read the list before it has been populated. You might want to reconsider your design so that environment-specific properties are only initialized once and preferably encapsulated so that they are accessed through accessor methods instead of static constants; this would also allow lazy, on-demand initialization, caching etc.
The best approach is not to create public static but not final fields. Because it can lead to problems with sharing this data between threads.
In your case, you can create a static final and immutable list.
The best way would be to have a static list initialized like that:
//Static final and unmodifiable list
private static final List<String> listPersons = createListPersons();
private static final createListPersons() {
List<String> listPersonsTemp = getPersonsFromEnvironmentVariable();
return Collections.unmodifiableList(listPersonsTemp);
}
public static final List<String> getListPersons(){
return listPersons;
}
This way you ensure that your list will is unmodifiable and accessed only via a getter. In this way the Sonar will not complain about the access modifiers.
Since the List contains Strings and is unmodifiable it can be considered immutable.
It is safer to use only immutable static objects. State or variables are safer managed in instances.
Modifiers should be declared in the correct order
The Java Language Specification recommends listing modifiers in the following order:
1. Annotations
2. public
3. protected
4. private
5. abstract
6. static
7. final
8. transient
9. volatile
10. synchronized
11. native
12. strictfp
Not following this convention has no technical impact, but will reduce the code's readability because most developers are used to the standard order.
Noncompliant Code Example
static public void main(String[] args) { // Noncompliant
}
Compliant Solution
public static void main(String[] args) { // Compliant
}
Using List.of(...) from the java.util.List package should resolve the SonarQube issue.
Returns an unmodifiable list containing an arbitrary number of elements.
I am wondering if there isn't a better way to convert whole Lists or Collections as the way I show in the following code example:
public static List<String> getAllNames(List<Account> allAccounts) {
List<String> names = new ArrayList<String>(allAccounts.size());
for (Account account : allAccounts) {
names.add(account.getName());
}
return names;
}
Every time I produce a method like this, I start thinking, isn't there a better way? My first thought would be to create maybe a solution with some generics and reflections, but this seems maybe a bit over sized and maybe a bit to slow when it comes to performance?
Take a look at Google's Guava library
Something like this should do it
final List<String> names = Lists.transform(myObjs, new Function<MyObject, String>() {
public String apply(final MyObject input) {
return input.getName();
}
});
With Guava, there is a more functional approach:
return FluentIterable.from(allAccounts).transform(new Function<Account,String>(){
public String apply(Account account){return account.getName();}
}).toImmutableList()
But that essentially does the same thing, of course.
BTW: the difference between this answer and RNJ's is that in my case the list will be created once, while in the other answer it's a live view. Both versions are valid, but for different scenarios.
I actually have exactly this kind of method in my personal library.
public static <TSource,TTarget> List<TTarget> castList(List<TSource> sourceList)
{
List<TTarget> targetList = new ArrayList<TTarget>(sourceList.size());
for (TSource t : sourceList) {
//This will throw a ClassCastException if the types are not compatible
//Be carefull
targetList.add((TTarget)t);
}
return targetList;
}
Usage is very simple because the compiler infers the type for TTarget.
List<Object> objects = new ArrayList<Object>();
objects.add("One");
objects.add("Two");
List<String> strings = castList(objects);
Regarding the performance:
I think using generics is no problem here. But the need to copy the whole array is another story.
There is no better way. Casting is a difficult and dangerous thing. In your example, your are not able to cast a String to a MyDataType or vice versa, aren't you?
You might create an own List-Implementation with some kind of toStringList()-Method if you need these more often.
There's a simple way but it is not type safe
List<A> a = new ArrayList<A>();
List<B> b = (List)a;
but then you have to override the implementation of toString() method of your class to return the getName() value.
But there's no type checking,
And as mentioned you can of course do instead a loop and call getName on every object
You could try using the Iterables and Function classes from the Guava libraries. You can create a new type of an Iterable using,
Iterable<String> newTypeIterable = Iterables.transform(oldTypeIterable, new Function<MyDataType, String> () {
#Override
public String apply(MyDataType from)
{
return from.getName();
}
});
Turns out you can do this with the Lists class too!
struggling a bit with something. I have built a proof of concept and googled but can't find reason.
I am currently trying to use an ArrayList as a static property in a class to store series of entries. The only problem is that everytime I try add to the Totalentries arraylist I get a nullPointerError.
Would appreciate some guidance as to where I am going wrong?
My Class:
import java.util.ArrayList;
public class Competition {
private static ArrayList totalentries;
public Competition(){
}
public void newEntry(){
totalentries.add("an Entry");
}
}
My Test Code:
public class testEntries {
/**
* #param args
*/
public static void main(String[] args) {
Competition myComp=new Competition();
myComp.newEntry(); //Null Pointer comes here!
myComp.newEntry();
myComp.newEntry();
myComp.newEntry();
myComp.newEntry();
myComp.newEntry();
myComp.toString();
}
}
You never instantiated totalentries in your Competition class.
You would need something like:
private static ArrayList totalentries = new ArrayList();
However, note that I would advise against keeping this "static". Otherwise, every "Competition" you create will be sharing the same list of entries, which is likely not what you really want.
Also, declare your types using interfaces, than instantiate with types. You may also want to use Generics here. So even better (and following standard naming conventions):
private List<String> totalEntries = new ArrayList<String>();
You never make an ArrayList. Try this:
private static ArrayList totalentries = new ArrayList();
though it would be better to use generics and get compile-time safety:
private static ArrayList<String> totalentries = new ArrayList<String>();
Since this list holds properties you wouldn't want it to be replaced so it would be even better if you were to define it like this:
private static final ArrayList<String> totalentries = new ArrayList<String>();
Really, though, none of these are good ideas because you could have multiple instances of your class changing totalentries at the same time. If that is your intent, that multiple Competitions use the one static totalentries for storage then you are better off keeping track of that data in a separate class.
If you are only using one Competition at a time then remove the static keyword.
totalentries is not initialized and it points to null. Make it like this:
private static List<String> totalentries = new ArrayList<String>();
The list must be created prior to usage, try
totalentries = new ArrayList();
You should also use List instead for the totalentries variable instead to allow exchanging te ArrayList with for example LinkedList.
Sometimes when I need lazily initialized field, I use following design pattern.
class DictionaryHolder {
private volatile Dictionary dict; // some heavy object
public Dictionary getDictionary() {
Dictionary d = this.dict;
if (d == null) {
d = loadDictionary(); // costy operation
this.dict = d;
}
return d;
}
}
It looks like Double Checking idion, but not exactly. There is no synchronization and it is possible for loadDictionary method to be called several times.
I use this pattern when the concurrency is pretty low. Also I bear in mind following assumptions when using this pattern:
loadDictionary method always returns the same data.
loadDictionary method is thread-safe.
My questions:
Is this pattern correct? In other words, is it possible for getDictionary() to return invalid data?
Is it possible to make dict field non-volatile for more efficiency?
Is there any better solution?
I personally feel that the Initialization on demand holder idiom is a good fit for this case. From the wiki:
public class Something {
private Something() {}
private static class LazyHolder {
private static final Something INSTANCE = new Something();
}
public static final Something getInstance() {
return LazyHolder.INSTANCE;
}
}
Though this might look like a pattern intended purely for singleton control, you can do many more cool things with it. For e.g. the holder class can invoke a method which in turn populates some kind of data.
Also, it seems that in your case if multiple threads queue on the loadDictionary call (which is synchronized), you might end up loading the same thing multiple times.
The simplest solution is to rely on the fact that a class is not loaded until it is needed. i.e. it is lazy loaded anyway. This way you can avoid having to do those checks yourself.
public enum Dictionary {
INSTANCE;
private Dictionary() {
// load dictionary
}
}
There shouldn't be a need to make it any more complex, certainly you won't make it more efficient.
EDIT: If Dictionary need to extend List or Map you can do.
public enum Dictionary implements List<String> { }
OR a better approach is to use a field.
public enum Dictionary {
INSTANCE;
public final List<String> list = new ArrayList<String>();
}
OR use a static initialization block
public class Dictionary extends ArrayList<String> {
public static final Dictionary INSTANCE = new Dictionary();
private Dictionary() { }
}
Your code is correct. To avoid loading more than once, synchronized{} would be nice.
You can remove volatile, if Dictionary is immutable.
private Dictionary dict; // not volatile; assume Dictionary immutable
public Dictionary getDict()
if(dict==null)
dict = load()
return dict;
If we add double checked locking, it's perfect
public Dictionary getDict()
if(dict==null)
synchronized(this)
if(dict==null)
dict = load()
return dict;
Double checked locking works great for immutable objects, without need of volatile.
Unfortunately the above 2 getDict() methods aren't theoretically bullet proof. The weak java memory model will allow some spooky actions - in theory. To be 100% correct by the book, we must add a local variable, which clutters our code:
public Dictionary getDict()
Dictionary local = dict;
if(local==null)
synchronized(this)
local = dict;
if(local==null)
local = dict = load()
return local;
1.Is this pattern correct? In other words, is it possible for getDictionary() to return invalid data?
Yes if it's okay that loadDictionary() can be called by several threads simultaneously and thus different calls to getDictionary() can return different objects. Otherwise you need a solution with syncronization.
2.Is it possible to make dict field non-volatile for more efficiency?
No, it can cause memory visibility problems.
3.Is there any better solution?
As long as you want a solution without syncronization (either explicit or implicit) - no (as far as I understand). Otherwise, there are a lot of idioms such as using enum or inner holder class (but they use implicit synchronization).
Just a quick stab at this but what about...
class DictionaryHolder {
private volatile Dictionary dict; // some heavy object
public Dictionary getDictionary() {
Dictionary d = this.dict;
if (d == null) {
synchronized (this) {
d = this.dict;
if (d == null) { // gated test for null
this.dict = d = loadDictionary(); // costy operation
}
}
return d;
}
}
Is it possible to make dict field non-volatile for more efficiency?
No. That would hurt visibility, i.e. when one thread initializes dict, other threads may not see the updated reference in time (or at all). This in turn would results in multiple heavy initializations, thus lots of useless work , not to mention returning references to multiple distinct objects.
Anyway, when dealing with concurrency, micro-optimizations for efficiency would be my last thought.
Initialize-on-demand holder class idiom
This method relies on the JVM only
intializing the class members upon
first reference to the class. In this
case, we have a inner class that is
only referenced within the
getDictionary() method. This means
DictionaryHolder will get initialized
on the first call to getDictionary().
public class DictionaryHolder {
private DictionaryHolder ()
{
}
public static Dictionary getDictionary()
{
return DictionaryLazyHolder.instance;
}
private static class DictionaryLazyHolder
{
static final DictionaryHolder instance = new DictionaryHolder();
}
}