This question already has answers here:
Anonymous code blocks in Java
(11 answers)
Closed 9 years ago.
It's kind of hard to exactly search for this. I've seen this in a few places and I've even tried it in code to see how it works but just so that I know exactly how they can be used and to make sure I wont be abusing them I thought i'd ask on here.
public void doSomethingSpecial()
{
String strHello = null;
// What is the following section in braces for
{
strHello = "Hello World"
}
for(int i = 0; i < 10; i++)
{
// What is the significance of them it in a loop?
{
strHello = "Hello";
// Do something else...
}
.
.
.
}
}
Can someone clarify what these brace blocks braces are for?
I assume they work like a method and would restrict the scope of anything within as long as it isn't specified outside the block, but is there another use?
What is the exact name for them?
Thanks in advance
The braces define scope. For example, if you define a local variable within the braces and assign a value to it like this:
{
int foo = 10;
}
Then foo's scope (i.e. the section of code where it is define and has a value) is limited to the area within the braces.
The same goes for your for loop. Within those braces, the counter i is defined and has meaning, but not outside. So this code would not compile:
for (int i = 0; i < 5; i++) {
// Do something with i
}
i = 10; // Won't compile. i is undefined as a variable.
The benefits of this are numerous in that you can precisely control the scope for different variables. You can also define the scope of things like exceptions in the context of exception handling, etc.
You can also do things like this:
int i = 0;
for (; i < 5; i++) {
// Do something with i.
}
for (; i < 10; i++) {
// Do something else with i
}
In this case i is defined in a larger scope space (that of the enclosing method or constructor) and the for loops are only incrementing its value. So you are sharing a variable among two different areas of scope.
Lastly you can use them outside of a method or constructor as initialization blocks in a class. They allow you to initialize member variables that, for example, cannot easily be initialized with a single line of code.
Within the class, they form a static initializer, it runs once when the class is loaded, which happens first.
Within the method, they mark a scope. They are basically useless in your code.
But if the code is the following
{
String str = "test";
System.out.println(str);
}
{
System.out.println(str);
}
The second print will report a compilation error, since the scope of str is in the first scope.
So found something I thought I would post on here for anyone as none of the other questions seem to exactly clarify this.
When used outside of a method in class scope:
public class doSomethingSPecial() {
{
System.out.println("This is a constructor");
}
public doSomeThingSpecial() {}
public doSomethingSpecial(String specialString) { }
public doSomethingSpecial(int specialNumber) { }
}
"The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors." - Java API Tutorial (Thanks to Soririous Delimanolis)
So the inline braces will be called each time a constructor is called.
As for the other questions regarding use within a method and loop the braces seem to be just to limit scope.
"In practice, though, if you find yourself using such a code block that's probably a sign that you want to refactor that block out to a method" - Credit to Robert Munteanu Top Answer: Anonymous code blocks in Java
That's basically everything I've come up with so far
Related
I have an issue regarding variable scope in the following piece of code. Can someone give a quick overview as to why java "cannot find the symbol" for output when it is printed? Thanks.
class Main
{
public static void main(String[] args) {
String text = "hello";
if (text.indexOf(" ") == -1) //if a space doesn't exist
{
String output = "one word";
}
else
{
String output = "more than one word";
}
System.out.println(output);
}
}
The variable output is only existent within the containing code block which currently seems to be within the if block and else block, if you want to access the variable output outside of the if and else block, you'll need to define it before the if block.
Local variables
A local variable is the one that is declared within a method or a constructor (not in the header). The scope and lifetime are limited to the method itself.
In addition to the local variables defined in a method, we also have variables that are defined in blocks, e.g. the if block and an the else block. The scope in this case is constrained by the block itself.
I know that there is a question like this on Stack Overflow but I want to know why we can't declare variables inside if statements so that we can save space by just utilizing the if scope.
For example, if I write:
if (int i) {
...
}
then I could use i only within the if scope, but if I write it outside of the if statement, then i variable should be in memory for the whole block.
if ( int i ) => int i is not a boolean expression, so this won't work.
if ( booleanExpr ){
int a = 5;
...
}
here a is a local variable within the if block. At the end of the if-block, it is removed from the stack and becomes unusable.
int a = 5;
if ( booleanExpr){
...
}
Here a is not local to the if block, but to the containing method. So, it will be on the stack during the entire execution of the method (starting from its declaration).
a could also be an instance or static variable to the class, then it's accessible in every method of the class (instance variables are not accessible in a static context, though)
why can't we declare variables in the if statement?
Because the Java Language Specification does not allow it.
if I write if(int i){} then I could use i only for if the scope
You can use blocks
public void someMethod() {
{
int i = 1; // visible only to the current block
} {
int i = 0; // visible only to the current block
if (i == 0) {
System.out.println("i = " + i);
}
}
// compiler error, because i is not visible outside the block
System.out.println(i);
}
But this decreases the readability of your code. So I would recommend to NOT use it.
An if statement is a test, so declaring a variable in an if does not make any sense.
Think about it, an if is for something like this:
if(a == 1){
// blan
}
If you declare a in the if condition, you are essentially comparing 2 static values.
Lots of languages let you declare an "iterator" vairable in a for loop:
if(int a = 0 ; a < somelist.length ; a++){
// Do something
}
// a is out of scope here
You can restrict the scope of your variable to make it visible only in the if statement like this:
System.out.println("Hello World!");
//use a codeblock to restrict access
{
int i = 4;
if(i!=0)
{
System.out.println("i = "+i);// this is OK
}
}
System.out.println("i = "+i);//this is not OK
why can't language support it
That's the wrong question to ask. The real question is:
Is there a compelling reason for the language to support it?
That is, is there a compelling reason to implement it, exhaustively test it for all possible edge cases, and maintain it in all future versions of the language?
In this case, no. There isn't. It might be handy in a small number of cases, but it's not a core feature of the language and isn't really necessary. So there's no compelling reason to make the implementation of the language more complex and incur significant cost now and well into the future to support it.
if is a conditional and there is no valid use-case when you declare a variable inside the conditional.
If your conditional is more complex, you can implement a few methods for it and inside those methods you can use those variables, however, if you need that variable outside the if, then define it outside the if in the correct scope.
private void generateActionPerformed(java.awt.event.ActionEvent evt) {
String number = getRandom(4);
int first,second,third,forth;
first = Integer.parseInt(number.substring(0,1));
second = Integer.parseInt(number.substring(1,2));
third = Integer.parseInt(number.substring(2,3));
forth = Integer.parseInt(number.substring(3));
}
private void reavealActionPerformed(java.awt.event.ActionEvent evt) {
}
so, i have for integer that i want to use it in the bottom method. Is there a way to carry(the same value) for integer first,second,third,forth into the bottom method(reavealActionPerformed) from the top method?
thank you
Nope. Please read up on variable scoping in Java. (More detailed explanation of scoping - http://www.java-made-easy.com/variable-scope.html )
In short, anything declared within a method (public/private/protected), is not available outside the method. More technically, the scope of the variable is the block where it is declared, including any sub block.
If you want to share the values, think about whether they can be part of your class. If they are logically your class' attributes, you can define them as instance variables.
Or you can try returning the values in an array and call this method when you need and the values will be 'returned' from the method.
In java how to use class variables in methods?
this is the code that I have
public class ExamQ3a {
String[] descriptionArr = new String[50];
static int[] codeArr = new int[50];
public static void displayItems(int count, int[] codeArr,
String[] descriptionArr) {
count = this.codeArr.length;
for (int i = codeArr.length; i < codeArr.length; i--) {
}
}
}
The line that is being highlighted here is the count = this.codeArr.length; the error that I am getting is that the non-static variables cannot be referenced from a static context. But I already made the variable static. So what gives?
So as per request only! not that I want to ask the whole question, just to know why I want to use static, this is a practice question
You are to develop a simple application system to manage the inventory
in a company. The system should be able to maintain a list of up to 50
items. Each item has a unique integer code and a description.
(a) Write Java statements that declare and create two arrays to store the
code and the description of the items.
(b) Write Java method with the following method signature:
public static void displayItems(int count, int[] codeArr, String[] descriptionArr)
This method displays the code and description of all items in the company
in tabular form with appropriate column heading.
Parameters: codeArr: the array that stores the codes of the items
descriptionArr: the array that stores the descriptions of the items
count: the number of items in the system
There is no this in the static world. Get rid of it. To explain, this refers to the current instance, and when you're dealing with static methods or variables, you're dealing with items associated with the class, not with any one particular instance. So change the code to:
count = codeArr.length;
Edit 1
As an aside, you don't want to bunch up your closing braces like } } } which makes your code very difficult to read and follow. White space is free, so might as well use it judiciously to improve code readability.
Edit 2
You state:
so how would I reference the array codeArr to the class variable codeArr?
You're inside of the class, and there's no need to use the class variable name here since it is assumed to be used. Just use the static variable or method name and you should be golden.
Edit 3
Your use of static for this type of variable gives the code a bad smell. I'm thinking that your entire program would be much better off if this were an instance variable and not a static variable. For more discussion on this, you may tell us why you decided to make the variable static.
Is you're going to reference a static variable having the same name as a method parameter you prefix the static variable with the name of the class. In this case it would be ExamQ3a.codeArr.
The other way to handle this is to pick different names for your method parameters, or start using a common prefix for instance/static variables.
Another point to note is that, in the following piece of code statement1 will never be executed:
for (int i = codeArr.length; i < codeArr.length; i--) { statement1; }
it should be either
int length = codeArr.length;
for (int i = 0; i < length; i++) { ... }
or
int length = codeArr.length;
for (int i = (length-1); i > -1 ; i--) { ... }
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Should I initialize variable within constructor or outside constructor
I was wondering, which is a better practice and why. Should I initialize class fields upon declaration, or should I do it in the constructor? Given that it's a simple one-line initialization.
class Dude
{
String name = "El duderino";
Dude() {
// irrelevant code
}
}
vs.
class Dude
{
String name;
Dude() {
name = "El duderino";
// irrelevant code
}
}
Edit: I am aware of the situations where one of the styles would be preferred over the other like in the case of executing initializer code that might throw an exception. What I'm talking about here are cases when both styles are absolutely equivalent. Both ways would accomplish the same task. Which should I use then?
If the member can only be set via an accessor (a "setter" method), I prefer the first style. It provides a hint that the initialized value is the default upon construction.
If the member can be specified during construction, I generally pass the default value to an appropriate constructor from constructor with fewer parameters. For example,
final class Dude {
private final String name;
Dude() {
this("El Duderino");
}
Dude(String name) {
this.name = name;
}
}
The first one is used usually to initialize static variable and should be used only for that purpose.
In this case, you should use the second method.
Please correct me if I am wrong.
It is best to declare variables inside the constructor for the sake of consistency. A variable may require something like a loop or an if-else statement to initialize it, which can not be done in the declaration without placing the operation inside of a method.
The exception to this rule is static variables, which should be declared outside of the constructor.
Single-line declarations cannot contain complex initialization logic.
If you initialize a variable as:
class AnotherClass
{
MyClass anObject = new MyClass(); //MyClass() throws a checked exception.
}
then you'll find that you cannot provide the initial value in the single line. You'll need to place such code in a block, that quite obviously goes inside a constructor (or in a non-static initialization block):
Using a constructor:
class AnotherClass
{
MyClass anObject;
AnotherClass()
{
try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/}
}
}
Using a initialization block:
class AnotherClass
{
MyClass anObject;
{
try{this.anObject = new MyClass();}catch(SomeException e){/*handle exception.*/}
}
}
I find that the latter makes for less understandable code, as the declaration and initialization are separated from each other, and the initialization does not occur in a constructor coded by the developer (although there is no difference at runtime).
The same goes for other complex routines involved in initialization of fields. For example, if you intend to initialize an Array or a Collection and set the contents of the array/collection to some default value, then you should do so inside a constructor:
class AnotherClass
{
Integer[] integers;
AnotherClass()
{
this.integers = new Integer[10];
for(Integer integer: integers)
{
integer = Integer.MIN_VALUE;
}
}
}