What do curly braces in Java mean by themselves? - java

I have some Java code that uses curly braces in two ways
// Curly braces attached to an 'if' statement:
if(node.getId() != null)
{
node.getId().apply(this);
}
// Curly braces by themselves:
{
List<PExp> copy = new ArrayList<PExp>(node.getArgs());
for(PExp e : copy)
{
e.apply(this);
}
}
outAMethodExp(node);
What do those stand-alone curly braces after the first if statement mean?

The only purpose of the extra braces is to provide scope-limit. The List<PExp> copy will only exist within those braces, and will have no scope outside of them.
If this is generated code, I assume the code-generator does this so it can insert some code (such as this) without having to worry about how many times it has inserted a List<PExp> copy and without having to worry about possibly renaming the variables if this snippet is inserted into the same method more than once.

I second what matt b wrote, and I'll add that another use I've seen of anonymous braces is to declare an implicit constructor in anonymous classes. For example:
List<String> names = new ArrayList<String>() {
// I want to initialize this ArrayList instace in-line,
// but I can't define a constructor for an anonymous class:
{
add("Adam");
add("Eve");
}
};
Some unit-testing frameworks have taken this syntax to another level, which does allow some slick things which look totally uncompilable to work. Since they look unfamiliar, I am not such a big fan myself, but it is worthwhile to at least recognize what is going on if you run across this use.

I agree with the scope limit answer, but would add one thing.
Sometimes you see a construct like that in the code of people who like to fold sections of their code and have editors that will fold braces automatically. They use it to fold up their code in logical sections that don't fall into a function, class, loop, etc. that would usually be folded up.

I'd actually guess that someone forgot an else statement.
There's rarely a good reason to even bother with creating additional block scopes. In this, and most cases, it's far more likely someone may have forgotten to type their control statement than it is that they were doing something clever.

They make an inner scope. Variable declared inside these braces is not visible outside of them. This also applies to C/C++.

Braces are also useful to reduce the scope in switch/case statements.
switch(foo) {
case BAR:
int i = ...
...
case BAZ:
int i = ... // error, "i" already defined in scope
}
But you can write
switch(foo) {
case BAR:{
int i = ...
...
}
case BAZ:{
int i = ... // OK
}
}

It is also used for initialization blocks.

They define a new scope which means that everything declared in this scope is not visible outside the curly braces.

As an interesting note: the braces actually enable a class of statements: declarations.
This is illegal: if(a) int f;
but this is legal: if(a) { int f; }

I think they just define an unnamed level of scope.

The bring a scope, copy will not be visible outside of it, so you can declare another variable with same name later. And it can be gathered by the garbage collector right after you exit that scope. In this case copy serves as a temporary variable, so it is a good example.

Related

Why can't you create a 1 statement function without curly braces?

So, in most programming language, if you are using a loop or an if, you can do it without curly braces if there is only a single statement in it, example:
if (true)
//Single statement;
for (int i = 0; i < 10; i++)
//Single Statement
while (true)
//Single statement
However, it doesn't work for functions, example:
void myFunction()
//Single Statement
So, my question, why doesn't it work for functions?
C++ needs it to disambiguate some constructs:
void Foo::bar() const int i = 5;
Now does the const belong to bar or i ?
Because language grammar forbids you to do that.
The Java grammar defines a method as following:
MethodDeclaration:
MethodHeader MethodBody
Methodbody as:
MethodBody:
Block
;
Which means either a Block (see below) or a single semicolon
Block:
{ BlockStatementsopt }
And a block as one or more statements within curly brackets.
However an if is defined as:
IfThenStatement:
if ( Expression ) Statement
Where no block is needed after the closing ) and therefore a single line is ok.
Why they chose to define it that way? One can only guess.
Grammar can be found here: http://docs.oracle.com/javase/specs/jls/se7/html/index.html
This is not a rule, in some languages you can (Python? Yes, I know that's really contrived example :)) ), in other you cannot.
You could very well extend your question for example to class and namespaces, for example, why not:
namespace Example
class Foo : public Bar
public: std::string myMethod()
return "Oh noes!";
right? At each level, that's just a single item, so why not skip the braces everywhere?
The answer is at the same time simple and complex.
In simple terms, it's about readability. Remember that you can layout your code as you like, since whitespaces are usually discarded by the compiler:
namespace Example class Foo : public Bar public: std::string myMethod() return "Oh noes!";
Well, that starts looking unreadable. Notice that if you add the braces back
namespace Example { class Foo : public Bar { public: std::string myMethod() {return "Oh noes!";}}}
then it, strangely, becomes somewhat comprehensible.
The actual problem is not readability (who cares anyways? I'm joking of course) but in the latter: comprehension. Not only you must be able to comprehend the code - the compiler must. And for the compiler there is no such thing as "oh, this looks like function". The compiler must be absolutely sure that it is a function. Also, it must be completely sure about where it starts, where it ends, and so on. And it must do that without looking at whitespaces too much, since C-family languages allow you to do add them in any quantities you like.
So, let's look again at the packed-up no-braces example
namespace Example class Foo : public Bar public : std::string myMethod() return "Oh noes!";
^ ^ ^^
I've marked some problematic symbols. Assuming you could define a grammar that handles it, please note how the meaning of ":" character changes. At one time it's denoting that you're specifying inheritance, at other point it's specifying access modifier to a method, at third place it's just namespace qualifier. Ok, the third one could be discarded if you were smart and noticed it's actually '::' symbol, not just a ':' character.
Also, meaning of keywords can change:
namespace Example class Foo : public Bar public : std::string myMethod() return "Oh noes!";
^^^^^^ ^^^^^^
At first place, it defines access modifier for inherited base class, at second place it defined access modifier for a method. What's more, at first place it's not meant to be followed by a ":" and at second place it's required to be followed by it!
So many rules, exceptions and corner cases, and we covered just 2 simple things: public and ':'. Now, imagine you are to specify the grammar for the whole language. You describe everything in the way you'd like to have. But, when you gather all the rules together, they at some point may start overlap and collide with each other. After adding Nth rule, it may happen that your 'compiler' would be unable to tell whether the 'public' actually marks inheritance, or starts a method:
namespace Example class Foo : public ::Bar public : std::string myMethod() return "Oh noes!";
^^^^^^^^ ^^^^^^^^
Note that I only changed the Bar to ::Bar. I only added a namespace qualifier, and now our rule of "public is followed by a colon" is trashed. As I now added a rule that "base class names may have namespace qualifiers", I also must add more rules to cover yet another corner cases - to remove the ambiguity of the meaning of "public" and ":" in this place.
To cut the long talk: the more rules, the more problem you have. The "compiler" grows, gets slower, eats more resources to work. This results in inability to handle large code files, or in frustration when the user must wait oh-so-long for that module to compile.
But what's worse for the user is, the more complex or ambiguous, the worse error messages are. Noone wants to use a compiler that is unable to parse some code and also unable to tell you what's wrong with it.
Remember in C++ what happens when you forget some ';' in a .h file? Or when you forget some }? Compiler reports you an error 30 or 300 lines farther. This is because the ';' and '{}' can be ommitted in many places, and for that 30 or 300 lines, the compiler simply does not yet know that's something wrong! Were the braces required everywhere, the point of error could be pinpointed faster.
The other way: making them optional at namespace, class, or function level, would remove the basic block-starts/block-ends markers and, at least:
could make the grammar ambiguous (and hence force to add more rules)
could hurt detecting (and reporting!) errors
any part of which noone really wants.
The C++ grammar is so complex, that it actually might be not possible to omit the braces at those places at all. For Java or plain C, I think it could be possible to make a grammar/compiler that would not require them, but would it would still hurt error reporting much. Especially in C which allows to use #include and macros. In early Java, the impact might be lesser, as the grammar is relatively simple, compared i.e. to current C++..
Probably the simplest, fastest, easiest to implement, and probably easiest to learn grammar would .. require braces (or any other delimiters) just about everywhere. Check LISP for example. But then, large part of your work would consist of constantly writing the same required markers, which many language-users simply does not like (i.e. I get nauseous when I need to work on some old code in VisualBasic with its "if then end if" yuck)
Now, if you look at brace-less language like Python - how does they solve it? They denote the block-starts/block-ends by .. intendation. In this language you must indent your code properly. If you don't indent it correctly, it will not compile at all, or it the loops/functions/etc will silently get their code messed up, because the compiler will not know what part does belong to which scope. No free lunch here again.
Basically a method(function) is a collection of statements that are grouped together to perform an operation. We group the statements for reusable. That is if you know that a set of instructions will used often in that case we create it as a separate function.
If you can perform the task in a single line of code, then why do you need to write a function?
Because the grammar of the language doesn't allow you to.
Here is the grammar for a function in C taken from the ISO/IEC 9899-1999 specification:
6.9.1 Function definitions
Syntax
1 function-definition:
declaration-specifiers declarator declaration-listopt compound-statement
The compound-statement part is the body of a function, and a compound statement is declared as
compound-statement:
{ block-item-listopt }
i.e. it starts and ends with braces.
An if, while or similar body can have a statement as its body.
(6.8.5) iteration-statement:
while ( expression ) statement
A statement can be one of several constructs.
statement:
labeled-statement
compound-statement
expression-statement
selection-statement
iteration-statement
jump-statement
of which only compound-statement requires the braces.
In c++ you need a compound statement to make a function body - which is actually surrounded with curly barces. It does not mean you need to have curly braces right immediately, following will compile just fine:
int foobar()
try {
return 1;
}
catch (...){return 0;}
You can't precisely say there are no one statement functions in C#. Anonymous methods could be one of them. Without single line statements we could not have Lambda expression in c#. The C# 3.0 wouldn't be exist.
There is no reason to add that extra parsing code in the compiler because the functionality is really useless, how many one line methods have you written that are not accessors or mutators? This has been dealt with in C# via properties but not yet in Java.
So the reason is, it's unlikely to be used considering most developers discourage leaving out optional bracket blocks anyway.

scope of local variable in enhanced for-loop

I have a rather simple question about variable scope.
I am familiar with the Enhanced For-Loops but I do not get why I should declare a new variable to keep each element. One example might clarify my question:
int[] ar = {1, 2, 3};
int i = 0;
for(i : ar) { // this causes an error if I do not declare a new variable: int i
// for(int i : ar) // this works fine
System.out.println(i);
}
So why I should declare this new variable? After all i is accessible inside the for loop. I did not want to use any previous value of i, just did not want to declare a new variable. (I guessed for other iterable items it might be faster using the same variable).
I guess that's how Enhanced For-Loops were built but does not this break the whole scope idea?
There is a question rising from the above behavior. Whether the compiler uses the same variable for the whole for loop and just updates its value or it creates a new variable for each iteration?
An interesting part is that if I keep both declaration of int i (before and inside the for loop) I even get a compiler error about
Duplicate local variable i
which makes (at least for me) things a bit more strange. So I cannot use the previous declared variable i inside the for loop but neither can I declare a new one inside it with the same name.
So why I should declare this new variable?
Because that's the way the syntax is defined.
After all i is accessible inside the for loop.
That's semantics. It's irrelevant to syntax.
I did not want to use any previous value of i, just did not want to declare a new variable. (I guessed for other iterable items it might be faster using the same variable).
Don 't guess about performance. Test and measure. But in this case there's nothing to measure, because any working code is faster than any non-working code.
Does this means that I have a local variable that gets different values or a different variable in each loop?
From a language point of view you have a different variable in each iteration. That’s why you can write:
for(final ItemType item: iterable) {
…
}
which makes a great difference as you can create inner class instances within the loop referring to the current element. With Java 8 you can use lambdas as well and even omit the final modifier but the semantic does not change: you don’t get the surprising results like in C#.
I guessed for other iterable items it might be faster using the same variable
That’s nonsense. As long as you don’t have a clue of how the produced code looks like you shouldn’t even guess.
But if you are interested in the details of Java byte code: within a stack frame local variables are addressed by a number rather than by a name. And the local variables of your program are mapped to these storage locations by reusing the storage of local variables that went out of scope. It makes no difference whether the variable exists during the entire loop or is “recreated” on every iteration. It will still occupy just one slot within the stack frame. Hence, trying to “reuse local variables” on a source code level makes no sense at all. It just makes your program less readable.
Just to have the reference here: The JLS Section 14.14.2, The enhanced for statement defines the enhanced for-loop to have the following structure (relevant for this question):
EnhancedForStatement:
for ( {VariableModifier} UnannType VariableDeclaratorId : Expression ) Statement
where UnannType can be summarized to be "a type" (primitive, reference...). So giving the type of the loop variable is simply obligatory according to the language specification - causing the (admittedly: somewhat confusing) observations described in the question.
The int i in the program is visible to the for loop and maybe other for loops beneath it (if present) under the same scope. But the i inside the for(int i : ar) is local to the for loop. Hence ending once the execution of loop is over. Thats the syntax defined for foreach loop that "you have to use a variable with scope limited to the loop".
So why I should declare this new variable? After all i is accessible inside the for loop. I did not want to use any previous value of i, just did not want to declare a new variable. (I guessed for other iterable items it might be faster using the same variable).
Why would there be any considerable performance benefit if you use the same variable tiny primitive variable over and over versus creating a one only when needed and which gets destroyed after loop ends.
I don't think anyone has answered the original question beyond just declaring that that is the syntax. We all know that that is the syntax. The question is, logically speaking, why?
After all, you can use a variable defined just before a loop as the loop variable, as long as the loop is a non-enhanced for loop!

Multiple Objects vs Changing One Object

I saw something today talking about this:
aClass something;
while (condition) {
something = new aClass();
...
}
while (condition) {
aClass something = new aClass();
...
}
It said you should use the second one rather than the first. Is this true, and if so, why?
Your first example leaks a useless variable into the outer scope.
The second method keeps the something variable only in the scope of that specific loop iteration.If you want to use the object outside the loop and / or keep the changes saved between iterations then you must use the first method.
Also, the second method doesn't define multiple variables, the compiler will usually optimize it in a way that makes sure only one variable is defined.
You should use the second example unless you need to use the object after the while loop is complete. If you don't need the variable in the outer scope it's better to declare it in the narrowest scope where it will be used (inside the loop). This simplifies the code for maintenance programmers who have to make sense of it.

if else condition in class constructor ... is it good practice?

I have written a constructor and passing one boolean flag to decide which value to set to class variable. Code is as follows
public PDFParagraph(PDFPhrase phrase,boolean isRtl) {
super(phrase);
if(isRtl)
this.setAlignment(Element.ALIGN_RIGHT);
else
this.setAlignment(Element.ALIGN_LEFT);
}
Now I am confused and not sure if I shall add if...else conditions in constructor. Is it good style to set the class varible value?
Thanks,
Hanumant.
Conditionals in constructors aren't problematic per se. However, in this instance, I'd be inclined to write your constructor like this:
public PDFParagraph(PDFPhrase phrase, boolean isRtl) {
super(phrase);
setAlignment(isRtl ? Element.ALIGN_RIGHT : Element.ALIGN_LEFT);
}
There is no style issue with using an if / else to do that. However:
You could write it more simply:
setAlignment(isRtl ? Element.ALIGN_RIGHT : Element.ALIGN_LEFT);
A lot of people (myself included) think that you should always put curly braces around the "then" and "else" statements.
On a related point: if you find yourself writing a constructor that looks like this:
public Thing(boolean cond, ...) {
super(...);
if (cond) {
// Lots of statements
} else {
// Lots of different statements
}
...
}
it is possibly an indication that you need to refactor your constructors. (Or possibly not ... it depends on the details.)
It might be more clear to users of your constructor if you just pass the initial alignment to set, especially if it's an Enum and those are the only possibilities. If however you're trying to restrict the initial alignment and it's something like a String, what you're doing seems fine. You still might want to consider an Enum for clarity though. It's easier to read than true or false being passed into a constructor.
Of course you can add if/else statements to the constructor.
It's usually best practice to keep methods as atomic (short and to-the-point) and clearly-defined as possible. This goes for the constructor also. You want the constructor to set up your object given the parameters you pass.
If you need an if/else, then you can put one in.
You can even go crazy and put a for loop in if you need to! ;)
I would recommend you use an enum and a switch statement instead of a boolean. What happens when you add another alignment?

java just curly braces

I was reading a book and there were a few example with programs that has just curly braces
for example
public static void main(String args[]){
//what is the uses of curly braces here.
{
//some code
}
}
It's a code block. The variables declared in there are not visible in the upper block (method body outside of these curlies), i.e. they have a more limited scope.
Be careful, it is NOT ALWAYS an initialisation block as others have suggested. In your case it is a variable scoping mechanism called a Code Block or block.
If it is outside of a method, then it is!
Example
public class MyClass {
{
// this is an initialisation block
}
}
However, if it is inside a method, it is NOT!
In this case (which is the case in your example), it is a code block. Anything initialised inside the curly braces is not visible outside
Example
public static void main(String args[]){
{
String myString = "you can't see me!";
}
System.out.println(myString); // this will not compile because myString is not visible.
}
This idea of how to use curly braces as a coding construct is a debated issue in the Java world . There are several explanations people come up with when they see curly braces by themselves. So Im going to try to answer your question from a practical perspective.
The implied question in your post here is, really - when/why are these used ? Practically speaking, the following cases might result in a lone code block :
1) The programmer wanted additionally scoping to reuse variable names without fear of collisions for clarity (i.e. making several objects of the same type in a unit test or database insertion block).
other possible reasons :
2) Forgotten if/else/for/while loop code that is under development.
3) Remaining artifact of a removed if/else/for/while clause.
4) Autogenerated code uses scoping to simplify the creation of several similar components with identical variable names (i.e. consider a gui generator that needed to make code for 100 radio buttons - rather than incrementing variable names per button, it could use scoping).
5) As a tiny, reusable, pastable logical block with minimal side effects : the programmer felt like a block of code in a method was so obscure, its variables and internal side effects should have minimal visibility to the outside world. That is, the programmer has used a code block as a poor-man's anonymous lambda function (albeit, one without a return value). In this pattern one might do something akin to the below :
//lets say I want to make a primary key for a dogs name in a database.
String dogNameKey=null;
{
long time = System.currentTimeInMilliseconds();
String theName = "spot";
dogName=theName+"_"+time;
}
Clearly, the simple strategy for naming this record (dogNameKey) is not worthy of an external method - its too simple. But at the same time, the "time" variable should have no bearing or accessibility outside the logic for making this name up - i.e. it shouldn't even be relevant to the method which contains this tiny key generating block. So, by using braces, I've scoped it out . If a labmda were possible, than all of this scoping could be wrapped in a single, anonymous function.
Now - I could paste several of these blocks, and the variable names would be identical, so it would be easy to scan them by eye.
*Thus, when you see curly braces by themselves - they usually are pretty important - either they implement a specific custom-scoping, or they are an artifact of an error or potentially of autogenerated code. Scoping can also be used to "start" the refactoring of a method without actually writing a new method, by separating out its independant parts ... although IDEs are much better at this than humans. *
You can logically separate your code by this in some cases, and in fact there's one use case I apply very often: demo data. E.g., you have some demo data generation class that creates demo data entries and inserts into your database. You place each single item in such a block, and can do copy-paste without changing variable names.
It is called Block
A block is a sequence of statements, local class declarations and local variable declaration statements within braces.
Also See:
Documents

Categories

Resources