Suppose, I have a method with a parameter of Object type.
The method returns nothing - void.
First it checks whether the parameter is not null (or any other check, like objectParam.isEnabled())
if (objectParam.isEnabled()) {
// ok
}
Now, if the condition is satisfied, I need local variables. If it's not, then I don't need any variables.
WHERE SHOULD I define them? Inside the "if scope" or just after the method header?
Of course, I can do it wherever I like, but which way should be a better practice?
I believe it's best practice to declare a variable as late as you can, in the most tightly nested scope that you can, ideally at the point where it's initialized with a useful value.
That makes it clearer where and how it's going to be used - when you're looking at the code where it's used, you won't have to look up very far to see the declaration.
In this particular case I disagree with the official Java Style Guide - and so does Josh Bloch. From Effective Java, 2nd edition, item 45:
The most powerful technique for minimizing the scope of a local variable is to declare it where it is first used.
So if you don't need the variable until you've executed a few other statements, don't declare it until that point.
If they're only used within the
if (...) { }
block then they should be declared at the top of that block.
The Java Style Guide has more details.
You should initialize them inside the narrowest scope where they are used, so inside the if block in this case.
void foo(Object obj){
if (obj != null) {
int a = 0;
...
}
}
If they aren't going to be used anywhere outside this block, there's no need to clutter up the method and confuse readers of your code with extra variables declared outside their required scope.
Related
This question already has answers here:
Should I instantiate instance variables on declaration or in the constructor?
(15 answers)
Closed 9 years ago.
When I use Java based on my C++ knowledge, I love to initialize variable using the following way.
public class ME {
private int i;
public ME() {
this.i = 100;
}
}
After some time, I change the habit to
public class ME {
private int i = 100;
public ME() {
}
}
I came across others source code, some are using 1st convention, others are using 2nd convention.
May I know which convention do you all recommend, and why?
I find the second style (declaration + initialization in one go) superior. Reasons:
It makes it clear at a glance how the variable is initialized. Typically, when reading a program and coming across a variable, you'll first go to its declaration (often automatic in IDEs). With style 2, you see the default value right away. With style 1, you need to look at the constructor as well.
If you have more than one constructor, you don't have to repeat the initializations (and you cannot forget them).
Of course, if the initialization value is different in different constructors (or even calculated in the constructor), you must do it in the constructor.
I have the practice (habit) of almost always initializing in the contructor for two reasons, one in my opinion it adds to readablitiy (cleaner), and two there is more logic control in the constructor than in one line. Even if initially the instance variable doesn't require logic, having it in the constructor gives more flexibility to add logic in the future if needed.
As to the concern mentioned above about multiple constructors, that's easily solved by having one no-arg constructor that initializes all the instance variables that are initilized the same for all constructors and then each constructor calls this() at the first line. That solves your reduncancy issues.
I tend to use the second one to avoid a complicated constructor (or a useless one), also I don't really consider this as an initialization (even if it is an initialization), but more like giving a default value.
For example in your second snippet, you can remove the constructor and have a clearer code.
If you initialize in the top or in constructor it doesn't make much difference .But in some case initializing in constructor makes sense.
class String
{
char[] arr/*=char [20]*/; //Here initializing char[] over here will not make sense.
String()
{
this.arr=new char[0];
}
String(char[] arr)
{
this.arr=arr;
}
}
So depending on the situation sometime you will have to initialize in the top and sometimes in a constructor.
FYI other option's for initialization without using a constructor :
class Foo
{
int i;
static int k;
//instance initializer block
{
//run's every time a new object is created
i=20;
}
//static initializer block
static{
//run's only one time when the class is loaded
k=18;
}
}
The only problem I see with the first method is if you are planning to add more constructors. Then you will be repeating code and maintainability would suffer.
I recommend initializing variables in constructors. That's why they exist: to ensure your objects are constructed (initialized) properly.
Either way will work, and it's a matter of style, but I prefer constructors for member initialization.
Both the options can be correct depending on your situation.
A very simple example would be: If you have multiple constructors all of which initialize the variable the same way(int x=2 for each one of them). It makes sense to initialize the variable at declaration to avoid redundancy.
It also makes sense to consider final variables in such a situation. If you know what value a final variable will have at declaration, it makes sense to initialize it outside the constructors. However, if you want the users of your class to initialize the final variable through a constructor, delay the initialization until the constructor.
One thing, regardless of how you initialize the field, use of the final qualifier, if possible, will ensure the visibility of the field's value in a multi-threaded environment.
I think both are correct programming wise,
But i think your first option is more correct in an object oriented way, because in the constructor is when the object is created, and it is when the variable should initialized.
I think it is the "by the book" convention, but it is open for discussion.
Wikipedia
It can depend on what your are initialising, for example you cannot just use field initialisation if a checked exception is involved. For example, the following:
public class Foo {
FileInputStream fis = new FileInputStream("/tmp"); // throws FileNotFoundException
}
Will cause a compile-time error unless you also include a constructor declaring that checked exception, or extend a superclass which does, e.g.:
public Foo() throws FileNotFoundException {}
I would say, it depends on the default. For example
public Bar
{
ArrayList<Foo> foos;
}
I would make a new ArrayList outside of the constructor, if I always assume foos can not be null. If Bar is a valid object, not caring if foos is null or not, I would put it in the constructor.
You might disagree and say that it's the constructors job to put the object in a valid state. However, if clearly all the constructors should do exactly the same thing(initialize foos), why duplicate that code?
I'm new to lambda and Java8. I'm facing following error.
Local variable log defined in an enclosing scope must be final or
effectively final
public JavaRDD<String> modify(JavaRDD<String> filteredRdd) {
filteredRdd.map(log -> {
placeHolder.forEach(text -> {
//error comes here
log = log.replace(text, ",");
});
return log;
});
return null;
}
The message says exactly what the problem is: your variable log must be final (that is: carry the keyword final) or be effectively final (that is: you only assign a value to it once outside of the lambda). Otherwise, you can't use that variable within your lambda statement.
But of course, that conflicts with your usage of log. The point is: you can't write to something external from within the lambda ... so you have to step back and look for other ways for whatever you intend to do.
In that sense: just believe the compiler.
Beyond that, there is one core point to understand: you can not use a local variable that you can write to. Local variables are "copied" into the context of the lambda at runtime, and in order to achieve deterministic behavior, they can only be read, and should be constants.
If your use case is to write to some object, then it should be a field of your enclosing class for example!
So, long story short:
local variables used (read) inside a lambda must act like a constant
you can not write to local variables!
or the other way round: if you need something to write to, you have to use a field of your surrounding class for example (or provide a call back method)
The reason for this limitation is the same as the reason for the Java language feature that local variables accessed from within (anonymous) inner classes must be (effectively) final.
This answer by rgettman gets into the details of it. rgettman explains the limitations in clear detail and I link to that answer because the behavior of lambda expressions should be same as that of anonymous inner classes. Note that such limitation does not exist for class or instance variables, however. The main reason for this is slightly complicated and I couldn't explain it better than what Roedy Green does it here. Copying here only so it is at one place:
The rule is anonymous inner classes may only access final local
variables of the enclosing method. Why? Because the inner class’s
methods may be invoked later, long after the method that spawned it
has terminated, e.g. by an AWT (Advanced Windowing Toolkit) event. The
local variables are long gone. The anonymous class then must work with
flash frozen copies of just the ones it needs squirreled away covertly
by the compiler in the anonymous inner class object. You might ask,
why do the local variables have to be final? Could not the compiler
just as well take a copy of non-final local variables, much the way it
does for a non-final parameters? If it did so, you would have two
copies of the variable. Each could change independently, much like
caller and callee’s copy of a parameter, however you would use the
same syntax to access either copy. This would be confusing. So Sun
insisted the local be final. This makes irrelevant that there are
actually two copies of it.
The ability for an anonymous class to access the caller’s final local
variables is really just syntactic sugar for automatically passing in
some local variables as extra constructor parameters. The whole thing
smells to me of diluted eau de kludge.
Remember method inner classes can`t modify any value from their surrounding method. Your second lambda expression in forecach is trying to access its surrounding method variable (log).
To solve this you can avoid using lambda in for each and so a simple for each and re-palace all the values in log.
filteredRdd.map(log -> {
for (String text:placeHolder){
log = log.replace(text,",");
}
return log;
});
In some use cases there can be a work around. The following code complains about the startTime variable not being effectively final:
List<Report> reportsBeforeTime = reports.stream()
.filter(r->r.getTime().isAfter(startTime))
.collect(Collectors.toList());
So, just copy the value to a final variable before passing it to lambda:
final LocalTime finalStartTime = startTime;
List<Report> reportsBeforeTime = reports.stream()
.filter(r->r.getTime().isAfter(finalStartTime))
.collect(Collectors.toList());
However, If you need to change a local variable inside a lambda function, that won't work.
If you do not want to create your own object wrapper, you can use AtomicReference, for example:
AtomicReference<String> data = new AtomicReference<>();
Test.lamdaTest(()-> {
//data = ans.get(); <--- can't do this, so we do as below
data.set("to change local variable");
});
return data.get();
One solution is to encapsulate the code in an enclosing (inner class). You can define this:
public abstract class ValueContext<T> {
public T value;
public abstract void run();
}
And then use it like this (example of a String value):
final ValueContext<String> context = new ValueContext<String>(myString) {
#Override
public void run() {
// Your code here; lambda or other enclosing classes that want to work on myString,
// but use 'value' instead of 'myString'
value = doSomethingWithMyString(value);
}};
context.run();
myString = context.value;
This question already has answers here:
Initialize class fields in constructor or at declaration?
(16 answers)
Closed 10 years ago.
What is the difference between the following two, and which is more preferable??
public class foo {
int i = 2;
}
public class foo {
int i;
foo() {
i = 2;
}
}
In your example, there is no difference in behavioural semantics. In Java, all instance field initializers (and instance blocks) are executed after superclass initialization, and before the body of the constructor; see JLS 12.5.
The difference lies in code readability and (in other examples) avoiding repetitious coding and fragility1. These need to be assessed on a case-by-case basis.
It is also worth noting that there are some cases where you have to initialize in the constructor; i.e. when the initialization depends on a constructor parameter.
1 - The repetitiousness and fragility issues are flip-sides of the same thing. If you have multiple constructors, the "initialize in constructor" approach tends to lead to repetition. And if you add extra fields, you might to add the initialization to all relevant constructors; i.e. fragility.
If you have two or more constructors and intialization value differs in each of them, then you should use constructor initialization as there is no way to do the same with member initialization...
however if you have just one constructor...you can use member initialization for better code clarity..
In particular this case there is no difference in these two variants. First variant is more preferable, because initializations of fields inside constructor, as usual, use external values from constructor arguments.
First of all I think the second example should look like this:
public class foo{
int i;
foo(){
i = 0;
}
}
Otherwise i is just a local variable in the C'tor scope.
Second, the first example shows initialization which is called before the class C'tor is invoked. this is good if you want this to happen no matter what C'tor is used.
It also enables you to declare i as readonly.
In your first example, i is an instance variable of class foo (better name would be Foo). It's initialised at class loading.
In your second example, i is also an instance varaible but in this case initialised in the foo() constructor.
There is no real difference here, and especially with primitives.
However, in a multi-threaded environment, if you do intend to initialise your ivars in your constructor, and those ivars are non-primitive, you need to avoid the risk of exposing a partially constructed object. The reason for this is that constructors aren't synchronised and can't have the synchronised keyword applied but then two threads can't be constructing the same object.
So, to avoid this, you should never expose this in your constructor. One way of doing so is to call non-final methods. Doing so, say calling an abstract method, allows some unknown code to do something with your unfinished object. Obviously, this can't be done if you initialise in your declaration.
p.s. I thought there was something on this in Effective Java but couldn't find anything.
I recently read some code that uses a special syntax regarding {}, I've asked a more experienced Java developer, but he also can't answer.
public void doSomething() {
someWorks();
{
someVariables;
someMoreWorks();
}
someEvenWorks();
{
...
}
}
Why does the code author put these lines inside {}? I guess that the variables declared within the {} will be released right after execution exits {}, right, because I can't access these outside the {} anymore?
Yes, the only difference is for scoping.
Occasionally this can be useful for throwaway code such as micro-benchmarks where you want to be able to cut and paste a block and make a minor change, then potentially reorder the blocks.
I would rarely (if ever) have something like this in "real" code though.
This gives him a nested scope to declare "more local" variables.
I guess that the variables declared within the {} will be released right after exit {}, right, because I can't access these outside the {} anymore?
Depends on your definition of "release" (they will most likely not be garbage collected until the method ends, so if this is important, you might want to null them out), but yes.
Other rarely seen uses of curly brackets include class and instance initializers:
class A {
static {
// some class initialization code
}
{
// some instance initialization code
}
}
The fact that the author put those variables in {} indicates the scope of those variables will only be that of the method defined by the {}; in turn, those variables will be up for garbage collection once method finishes execution.
This question already has answers here:
Should I instantiate instance variables on declaration or in the constructor?
(15 answers)
Closed 9 years ago.
When I use Java based on my C++ knowledge, I love to initialize variable using the following way.
public class ME {
private int i;
public ME() {
this.i = 100;
}
}
After some time, I change the habit to
public class ME {
private int i = 100;
public ME() {
}
}
I came across others source code, some are using 1st convention, others are using 2nd convention.
May I know which convention do you all recommend, and why?
I find the second style (declaration + initialization in one go) superior. Reasons:
It makes it clear at a glance how the variable is initialized. Typically, when reading a program and coming across a variable, you'll first go to its declaration (often automatic in IDEs). With style 2, you see the default value right away. With style 1, you need to look at the constructor as well.
If you have more than one constructor, you don't have to repeat the initializations (and you cannot forget them).
Of course, if the initialization value is different in different constructors (or even calculated in the constructor), you must do it in the constructor.
I have the practice (habit) of almost always initializing in the contructor for two reasons, one in my opinion it adds to readablitiy (cleaner), and two there is more logic control in the constructor than in one line. Even if initially the instance variable doesn't require logic, having it in the constructor gives more flexibility to add logic in the future if needed.
As to the concern mentioned above about multiple constructors, that's easily solved by having one no-arg constructor that initializes all the instance variables that are initilized the same for all constructors and then each constructor calls this() at the first line. That solves your reduncancy issues.
I tend to use the second one to avoid a complicated constructor (or a useless one), also I don't really consider this as an initialization (even if it is an initialization), but more like giving a default value.
For example in your second snippet, you can remove the constructor and have a clearer code.
If you initialize in the top or in constructor it doesn't make much difference .But in some case initializing in constructor makes sense.
class String
{
char[] arr/*=char [20]*/; //Here initializing char[] over here will not make sense.
String()
{
this.arr=new char[0];
}
String(char[] arr)
{
this.arr=arr;
}
}
So depending on the situation sometime you will have to initialize in the top and sometimes in a constructor.
FYI other option's for initialization without using a constructor :
class Foo
{
int i;
static int k;
//instance initializer block
{
//run's every time a new object is created
i=20;
}
//static initializer block
static{
//run's only one time when the class is loaded
k=18;
}
}
The only problem I see with the first method is if you are planning to add more constructors. Then you will be repeating code and maintainability would suffer.
I recommend initializing variables in constructors. That's why they exist: to ensure your objects are constructed (initialized) properly.
Either way will work, and it's a matter of style, but I prefer constructors for member initialization.
Both the options can be correct depending on your situation.
A very simple example would be: If you have multiple constructors all of which initialize the variable the same way(int x=2 for each one of them). It makes sense to initialize the variable at declaration to avoid redundancy.
It also makes sense to consider final variables in such a situation. If you know what value a final variable will have at declaration, it makes sense to initialize it outside the constructors. However, if you want the users of your class to initialize the final variable through a constructor, delay the initialization until the constructor.
One thing, regardless of how you initialize the field, use of the final qualifier, if possible, will ensure the visibility of the field's value in a multi-threaded environment.
I think both are correct programming wise,
But i think your first option is more correct in an object oriented way, because in the constructor is when the object is created, and it is when the variable should initialized.
I think it is the "by the book" convention, but it is open for discussion.
Wikipedia
It can depend on what your are initialising, for example you cannot just use field initialisation if a checked exception is involved. For example, the following:
public class Foo {
FileInputStream fis = new FileInputStream("/tmp"); // throws FileNotFoundException
}
Will cause a compile-time error unless you also include a constructor declaring that checked exception, or extend a superclass which does, e.g.:
public Foo() throws FileNotFoundException {}
I would say, it depends on the default. For example
public Bar
{
ArrayList<Foo> foos;
}
I would make a new ArrayList outside of the constructor, if I always assume foos can not be null. If Bar is a valid object, not caring if foos is null or not, I would put it in the constructor.
You might disagree and say that it's the constructors job to put the object in a valid state. However, if clearly all the constructors should do exactly the same thing(initialize foos), why duplicate that code?