What is the rationale behind making this kind of code valid in java? Does it exist for some particular reason or is it just a byproduct of other Java language design decisions? Can't you just use the consructor to achieve the same effect?
class Student
{
{
System.out.println("Called when Student class is instantiated.");
}
}
One point is that it will execute whichever constructor is called. If you have several constructors and they don't call each other (for whatever reason, e.g. each wanting to call a directly-corresponding superclass constructor) this is one way of making sure the same code is executed for all constructors, without putting it in a method which could be called elsewhere.
It's also potentially useful when you're writing an anonymous class - you can't write a constructor, but you can write an initializer block. I've seen this used for JMock tests, for example.
It's called an initializer block.
The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.
It called init block. In such block you can perform logic that are same for all constructions also you can separate declaration and initialization of same fields.
upd and of course double brace initialization, like
List<Integer> answers = new ArrayList<Integer>(){{add(42);}}
This is an initialization block. As mentioned by Matt Ball, they are copied into each constructor.
You might be interested to know about static initialization blocks (also in Matt's link):
public class Foo {
static {
System.out.println("class Foo just got initialized!");
}
{
System.out.println("an instance of Foo just got initialized!");
}
}
Related
If I try to assign a value to a variable in a class, but outside a method I get an error.
class one{
Integer b;
b=Integer.valueOf(2);
}
but, if I initialize it during the creation, it works.
class one{
Integer b=Integer.valueOf(2);
}
Inside a method, it works in both cases.
you need to do
class one{
Integer b;
{
b=Integer.valueOf(2);
}
}
as statements have to appear in a block of code.
In this case, the block is an initailiser block which is added to every constructor (or the default constructor in this case) It is run after any call to super() and before the main block of code in any constructor.
BTW: You can have a static initialiser block with static { } which is called when the class is initialised.
e.g.
class one{
static final Integer b;
static {
b=Integer.valueOf(2);
}
}
Because the assignments are statements and statements are allowed only inside blocks of code(methods, constructors, static initializers, etc.)
Outside of these only declarations are allowed.
This :
class one{
Integer b=Integer.valueOf(2);
}
is a declaration with an initializer. That's why is accepted
A more general answer would be that the class body is about declarations, not statements. There is special provision for statements occuring in class body, but they have to be marked explicitly as either class initializers or instance initializers.
In Java, when defining a class, you can define variables with default values and add methods. Any executable code (such as assignments) MUST be contained in a method.
This is the way java works, you cannot add non-declaration code (sorry i don't know the correct term) inside the class, that code should be inside methods.
I think terminology-wise, couple of other answers are slightly off. Declarations are also statements. In fact, they are called "declaration statements", which are one of the three kinds of statements. An assignment statement is one form of "expression statement" and can be used only in constructs such as methods, constructors, and initializers. Check out the Statements section in this Oracle's tutorial link.
Methods have the responsibility to perform mutations on the member variables. If the member variable needs to be initialized, java provides a way to do it during construction, class definition (latter case). But the mutation cannot be performed during definition.(former case). It is usually done at the method level.
Objects are meant to hold the state, while methods are meant to operate on that state.
I was wondering how to achieve the local static variable in java. I know Java wount support it. But what is the better way to achieve the same? I donot want the other methods in my class to access the variable, but it should retain the value across the invocations of the method.
Can somebody please let me know.
I don't think there is any way to achieve this. Java does not support 'local static' a la C, and there is no way to retrofit this while still keeping your sourcecode "real Java"1.
I donot want the other methods in my class to access the variable, but it should retain the value across the invocations of the method.
The best thing would be to make it an ordinary (private) static, and then just don't access it from other methods. The last bit should be easy ... 'cos you are writing the class.
1 - I suppose you could hack something together that involves preprocessing your code, but that will make all sorts of other things unpleasant. My advice is don't go there: it is not worth the pain.
Rather than trying to actually protect the variable, making the code more obscure and complicated, consider logical protection by comment and placement. I declare normal fields at the start of the class, but a field that should only be accessed from one method just before that method. Include a comment saying it should only be used in the one method:
// i should be used only in f
private int i;
/**
* Documentation for f().
*/
public void f(){
System.out.println(i++);
}
What you want is the ability to constraint intermediate computation results within the relevant method itself. To achieve this, you can refer to the following code example. Suppose you want to maintain a static variable i across multiple calls of m(). Instead of having such a static variable, which is not feasible for Java, you can encapsulate variable i into a field of a class A visible only to m(), create a method f(), and move all your code for m() into f(). You can copy, compile, and run the following code, and see how it works.
public class S {
public void m() {
class A {
int i;
void f() {
System.out.println(i++);
}
}
A a = new A();
a.f();
a.f();
a.f();
}
public static void main(String[] args) {
S s = new S();
s.m();
}
}
In theory, yes - but not in conventional manners.
What I would do to create this:
Create that Object in a totally different class, under the private modifier, with no ability to be accessed directly.
Use a debugging tool, such as the JDI to find that variable in the other class, get it's ObjectReference and manipulate directly or create a new variable which references to that object, and use that variable, which references to the object, in your method.
This is quite complicated, as using the JDI is tough, and you would need to run your program on 2 processes.
If you want to do this, I suggest looking into the JDI, but my honest answer would be to look for another solution.
Based on dacongy's idea of using a method local class I created a simple solution:
public class Main {
public static String m() {
class Statics {
static String staticString;
}
if (Statics.staticString == null)
Statics.staticString = "My lazy static method local variable";
return Statics.staticString;
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is Double Brace initialization in Java?
While looking at some legacy code I came across something very confusing:
public class A{
public A(){
//constructor
}
public void foo(){
//implementation ommitted
}
}
public class B{
public void bar(){
A a = new A(){
{ foo(); }
}
}
}
After running the code in debug mode I found that the anonymous block { foo() } is called after the constructor A() is called. How is the above functionally different from doing:
public void bar(){
A a = new A();
a.foo();
}
? I would think they are functionally equivalent, and would think the latter way is the better/cleaner way of writing code.
{ foo(); }
is called instance initializer.
why?
As per java tutorial
The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.
"Instance initializers are a useful alternative to instance variable initializers whenever: (1) initializer code must catch exceptions, or (2) perform fancy calculations that can't be expressed with an instance variable initializer. You could, of course, always write such code in constructors. But in a class that had multiple constructors, you would have to repeat the code in each constructor. With an instance initializer, you can just write the code once, and it will be executed no matter what constructor is used to create the object. Instance initializers are also useful in anonymous inner classes, which can't declare any constructors at all."Source
This was also quoted in this answer.
Unless the runtime class of the object is accessed (by means of calling getClass()) and needs to be different from A for some reason (for instance because it serves as super type token), there is indeed no difference, and simply invoking foo() after construction would indeed be the more common idiom.
I ran across a class that was set up like this:
public class MyClass {
private static boolean started = false;
private MyClass(){
}
public static void doSomething(){
if(started){
return;
}
started = true;
//code below that is only supposed to run
//run if not started
}
}
My understanding with static methods is that you should not use class variables in them unless they are constant, and do not change. Instead you should use parameters. My question is why is this not breaking when called multiple times by doing MyClass.doSomething(). It seems to me like it should not work but does. It will only go pass the if statement once.
So could anyone explain to me why this does not break?
The method doSomething() and the variable started are both static, so there is only one copy of the variable and it is accessible from doSomething(). The first time doSomething() is called, started is false, so it sets started to true and then does... well, something. The second and subsequent times it's called, started is true, so it returns without doing anything.
There's no reason why using a static variable wouldn't work. I'm not saying it's particularly good practice, but it will work.
What should happen is:
The first call is made. The class is initialised, started is false.
doSomething is called. The if fails and the code bypasses it. started is set to true and the other code runs.
doSomething is called again. The if passes and execution stops.
The one thing to note is that there is no synchronization here, so if doSomething() was called on separate threads incredibly close together, each thread could read started as false, bypass the if statement and do the work i.e. there is a race condition.
The code given is not thread safe. The easy way to make this code thread safe would be to do something like
public class MyClass {
private static AtomicBoolean started = new AtomicBoolean(false);
private MyClass(){
}
public static void doSomething(){
boolean oldValue = started.getAndSet(true);
if (oldValue)
return;
}
//code below that is only supposed to run
//run if not started
}
}
This should be thread safe as the AtomicBoolean getAndSet is synchronized.
Admittedly this is not an issue if you do not use threads (please note that a webapp can use quite a lot of threads handling various requests without you being aware of that).
It's not particularly nice code - generally designs should use object instances where state changes, but there's nothing illegal with it.
My understanding with static methods is that you should not use class variables in them unless they are constant, and do not change.
You seem to have extrapolated from a design guideline to a language feature. Read one of the many Java tutorials available on line as to what is actually allowed in the language. You can use non-final static fields freely in static methods, but it leads to procedural rather than object-oriented code.
Instead you should use parameters.
It's hard to see how an started parameter would be used - if the caller knew that the process has been started, why would they call the method?
Within static method, you are allowed to invoke or access static members within the same class.
Disregarding multiple threads scenarios,
The first call to doSomething will make the boolean static variable to true, therefore, the second call will execute the code of if block which just simply exit the method.
You static method is talking to a static class variable, so it should be fine. You could think of this as global code and a global variable, tho it IS in the namespace of the class.
If you tried to access a non-static member variable:
private int foo = 0;
from within the static method, the compiler will and should complain.
started is false - initial state.
MyClass.doSomething() - statered is now true
MyClass.doSomething() - started is STILL true
MyClass foo = new MyClass();
foo.started -> it's STILL true, because it's static
foo.doSomething() - not sure you can do this in Java, but if you can, it's be STILL TRUE!
Now, there are issues in the above code with thread safety, but aside from that, it appears to be working as designed.
Just remember the thumb rule that "Static variables are class-level variables and all non-static variables are instance variables". Then you won't have any confusion at all!
i.e.
For static variable, All references made in code to the variable point to same memory location. And for non-static variable, new memory allocation is done whenever new instance of that class is created (so every reference made in code to the variable points to a different memory location allocated for calling class instance).
The code above works completely well (unless it runs in a multithreaded environment). Why do you think it should break?
My understanding with static methods is that you should not use class variables in them unless they are constant, and do not change
I guess only static members can be accessed. It need not be constant!
My question is why is this not breaking when called multiple times by doing MyClass.doSomething(). It seems to me like it should not work but does. It will only go pass the if statement once
Per the existing logic. Only the first call runs the //code to be run part
I've been programming in C# and Java recently and I am curious where the best place is to initialize my class fields.
Should I do it at declaration?:
public class Dice
{
private int topFace = 1;
private Random myRand = new Random();
public void Roll()
{
// ......
}
}
or in a constructor?:
public class Dice
{
private int topFace;
private Random myRand;
public Dice()
{
topFace = 1;
myRand = new Random();
}
public void Roll()
{
// .....
}
}
I'm really curious what some of you veterans think is the best practice. I want to be consistent and stick to one approach.
My rules:
Don't initialize with the default values in declaration (null, false, 0, 0.0…).
Prefer initialization in declaration if you don't have a constructor parameter that changes the value of the field.
If the value of the field changes because of a constructor parameter put the initialization in the constructors.
Be consistent in your practice (the most important rule).
In C# it doesn't matter. The two code samples you give are utterly equivalent. In the first example the C# compiler (or is it the CLR?) will construct an empty constructor and initialise the variables as if they were in the constructor (there's a slight nuance to this that Jon Skeet explains in the comments below).
If there is already a constructor then any initialisation "above" will be moved into the top of it.
In terms of best practice the former is less error prone than the latter as someone could easily add another constructor and forget to chain it.
I think there is one caveat. I once committed such an error: Inside of a derived class, I tried to "initialize at declaration" the fields inherited from an abstract base class. The result was that there existed two sets of fields, one is "base" and another is the newly declared ones, and it cost me quite some time to debug.
The lesson: to initialize inherited fields, you'd do it inside of the constructor.
The semantics of C# differs slightly from Java here. In C# assignment in declaration is performed before calling the superclass constructor. In Java it is done immediately after which allows 'this' to be used (particularly useful for anonymous inner classes), and means that the semantics of the two forms really do match.
If you can, make the fields final.
Assuming the type in your example, definitely prefer to initialize fields in the constructor. The exceptional cases are:
Fields in static classes/methods
Fields typed as static/final/et al
I always think of the field listing at the top of a class as the table of contents (what is contained herein, not how it is used), and the constructor as the introduction. Methods of course are chapters.
In Java, an initializer with the declaration means the field is always initialized the same way, regardless of which constructor is used (if you have more than one) or the parameters of your constructors (if they have arguments), although a constructor might subsequently change the value (if it is not final). So using an initializer with a declaration suggests to a reader that the initialized value is the value that the field has in all cases, regardless of which constructor is used and regardless of the parameters passed to any constructor. Therefore use an initializer with the declaration only if, and always if, the value for all constructed objects is the same.
There are many and various situations.
I just need an empty list
The situation is clear. I just need to prepare my list and prevent an exception from being thrown when someone adds an item to the list.
public class CsvFile
{
private List<CsvRow> lines = new List<CsvRow>();
public CsvFile()
{
}
}
I know the values
I exactly know what values I want to have by default or I need to use some other logic.
public class AdminTeam
{
private List<string> usernames;
public AdminTeam()
{
usernames = new List<string>() {"usernameA", "usernameB"};
}
}
or
public class AdminTeam
{
private List<string> usernames;
public AdminTeam()
{
usernames = GetDefaultUsers(2);
}
}
Empty list with possible values
Sometimes I expect an empty list by default with a possibility of adding values through another constructor.
public class AdminTeam
{
private List<string> usernames = new List<string>();
public AdminTeam()
{
}
public AdminTeam(List<string> admins)
{
admins.ForEach(x => usernames.Add(x));
}
}
What if I told you, it depends?
I in general initialize everything and do it in a consistent way. Yes it's overly explicit but it's also a little easier to maintain.
If we are worried about performance, well then I initialize only what has to be done and place it in the areas it gives the most bang for the buck.
In a real time system, I question if I even need the variable or constant at all.
And in C++ I often do next to no initialization in either place and move it into an Init() function. Why? Well, in C++ if you're initializing something that can throw an exception during object construction you open yourself to memory leaks.
The design of C# suggests that inline initialization is preferred, or it wouldn't be in the language. Any time you can avoid a cross-reference between different places in the code, you're generally better off.
There is also the matter of consistency with static field initialization, which needs to be inline for best performance. The Framework Design Guidelines for Constructor Design say this:
✓ CONSIDER initializing static fields inline rather than explicitly using static constructors, because the runtime is able to optimize the performance of types that don’t have an explicitly defined static constructor.
"Consider" in this context means to do so unless there's a good reason not to. In the case of static initializer fields, a good reason would be if initialization is too complex to be coded inline.
Being consistent is important, but this is the question to ask yourself:
"Do I have a constructor for anything else?"
Typically, I am creating models for data transfers that the class itself does nothing except work as housing for variables.
In these scenarios, I usually don't have any methods or constructors. It would feel silly to me to create a constructor for the exclusive purpose of initializing my lists, especially since I can initialize them in-line with the declaration.
So as many others have said, it depends on your usage. Keep it simple, and don't make anything extra that you don't have to.
Consider the situation where you have more than one constructor. Will the initialization be different for the different constructors? If they will be the same, then why repeat for each constructor? This is in line with kokos statement, but may not be related to parameters. Let's say, for example, you want to keep a flag which shows how the object was created. Then that flag would be initialized differently for different constructors regardless of the constructor parameters. On the other hand, if you repeat the same initialization for each constructor you leave the possibility that you (unintentionally) change the initialization parameter in some of the constructors but not in others. So, the basic concept here is that common code should have a common location and not be potentially repeated in different locations. So I would say always put it in the declaration until you have a specific situation where that no longer works for you.
There is a slight performance benefit to setting the value in the declaration. If you set it in the constructor it is actually being set twice (first to the default value, then reset in the ctor).
When you don't need some logic or error handling:
Initialize class fields at declaration
When you need some logic or error handling:
Initialize class fields in constructor
This works well when the initialization value is available and the
initialization can be put on one line. However, this form of
initialization has limitations because of its simplicity. If
initialization requires some logic (for example, error handling or a
for loop to fill a complex array), simple assignment is inadequate.
Instance variables can be initialized in constructors, where error
handling or other logic can be used.
From https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html .
I normally try the constructor to do nothing but getting the dependencies and initializing the related instance members with them. This will make you life easier if you want to unit test your classes.
If the value you are going to assign to an instance variable does not get influenced by any of the parameters you are going to pass to you constructor then assign it at declaration time.
Not a direct answer to your question about the best practice but an important and related refresher point is that in the case of a generic class definition, either leave it on compiler to initialize with default values or we have to use a special method to initialize fields to their default values (if that is absolute necessary for code readability).
class MyGeneric<T>
{
T data;
//T data = ""; // <-- ERROR
//T data = 0; // <-- ERROR
//T data = null; // <-- ERROR
public MyGeneric()
{
// All of the above errors would be errors here in constructor as well
}
}
And the special method to initialize a generic field to its default value is the following:
class MyGeneric<T>
{
T data = default(T);
public MyGeneric()
{
// The same method can be used here in constructor
}
}
"Prefer initialization in declaration", seems like a good general practice.
Here is an example which cannot be initialized in the declaration so it has to be done in the constructor.
"Error CS0236 A field initializer cannot reference the non-static field, method, or property"
class UserViewModel
{
// Cannot be set here
public ICommand UpdateCommad { get; private set; }
public UserViewModel()
{
UpdateCommad = new GenericCommand(Update_Method); // <== THIS WORKS
}
void Update_Method(object? parameter)
{
}
}