Why can't I see method-local variables outside the method? - java

I'm new to Java and wanted some clarification, I understand that I'm declaring an int variable of x inside the method's parameters but why is it that 'result' can not be resolved to a variable.
public class Methods{
public static void main(String[] args) {
//f(x) = x * x
square(5);
System.out.println(result);
}
//This method
static int square(int x) {
int result = x * x;
}

You can, but note that local variable are only defined in their respected functions. So even though result is defined in square(), it's not defined in main(). So what you want to do is return a value for your square function and store that in a variable inside main() like so:
public static void main(String[] args) {
int myResult = square(5);
System.out.println(myResult);
}
//This method
static int square(int x) {
int result = x * x; // Note we could just say: return x * x;
return result;
}
Example Here

Since you are beginner, I will explain it bit thoroughly
Rule 1:Local variables are declared in methods, constructors, or blocks.
Rule 2:Local variables are created when the method, constructor or block is entered and the variable will be destroyed once it exits the method, constructor or block.
Rule 3:There is no default value for local variables so local variables should be declared and an initial value should be assigned before the first use.
public class Methods{
public static void main(String[] args) {
//f(x) = x * x
square(5);
System.out.println(result); //result! who are you?
//Main will not recognize him because of rule 3.
}
static int square(int x) {
int result = x * x; //you did it as said in rule 1
}//variable result is destroyed because of rule 2.
Please go thorough comments in code.
Well solution for your code is:
public class Methods{
public static void main(String[] args) {
//f(x) = x * x
int result=square(5);
System.out.println(result); //result! who are you?
//Main will not recognize him because of rule 3.
}
static int square(int x) {
int result1 = x * x; //you did it as said in rule 1
return result1;
}

Related

Data hiding in interface java

interface My{
int x = 10;
}
class Temp implements My{
int x = 20;
public static void main(String[] s){
System.out.println(new Temp().x);
}
}
This prints the result as 20. Is there any way that I can access the x that belongs to the interface in the class?
You need to do an explicit cast to the interface type:
System.out.println(((My)new Temp()).x);
Note however that x is not bound to any instance of My. Interface fields are implicitly static and final (more of constants), meaning the above can be done using:
System.out.println(My.x);
You can always use this.
interface My {
int x = 10;
}
class Temp implements My {
int x = 20;
public static void main(String[] s) {
System.out.println(new Temp().x); // 20
System.out.println(My.x); // 10
}
}
fields of an Interface are always static.

Final non-static data member

If you are not allowed to initialize a final non-static data member twice, then how can I set x to something that I want in the following example?
class Temp6
{
final int x;
Temp6()
{
System.out.println(this.x);
this.x=10;
}
public static void main(String[]s)
{
Temp6 t1 = new Temp6();
System.out.println(t1.x);
}
}
Java by default gives x a value of 0, so how can I change it to 10?.
A variable marked final in Java can only be initialized once.
Simply declaring x with final int x; does not initialize it. Therefore, it is legal to assign to x in the Temp6 constructor. However, you would not be able to assign a different value to x after the constructor.
That is, the assignment to t1.x in the following:
public static void main(String[] s) {
Temp6 t1 = new Temp6();
t1.x = 11; // ERROR
}
is not legal.
Initialize final variables in the class constructor.
public class Blam
{
private final int qbert;
public Blam(int qbertValue)
{
qbert = qbertValue;
}
}
Reading this.x in your code should give an error, because final variables are not initialized upon declaration. t1.x should be 10 because x is definitely assigned at the end of the sole constructor.
You have to swap the two lines in the constructor for it to compile and it will be 10 there.
class Temp {
int x; // declaration and definition; defaulted to 0
final int y; // declaration, not initialized
Temp() {
System.out.println(x); // prints 0
x = 1;
System.out.println(x); // prints 1
x = 2; // last value, instance.x will give 2
System.out.println(y); // should be a compiler error: The blank final field y may not have been initialized
y = 3; // definite assignment, last and only value, instance.y will be 3 whereever used
System.out.println(y); // prints 3
y = 4; // compile error: The final field y may already have been assigned
}
}
I never thought about this before, interesting point here.
Final field variables behave like local variables in methods, they must be explicitly assigned before usage (definite assignment is hard to formalize, see JLS reference, but it's quite logical).
If you want to give a value to x from outside, you could do it like this:
public class Temp {
private final int x;
public Temp(int x) {
this.x = x;
}
public int getX() { return this.x; }
public static void main(String[] args) {
Temp temp = new Temp(10);
System.out.println(temp.getX()); // 10
}
}
final variable are java constants. They should be initialized before class loads.
final int x=10;
If your final variable is static then it's not like you have to give the value at the declaration itself, you can have something like -
class Demo {
static final int x;
static {
x = 10;
}
}
static block gets executed only once, at the time of class loading

Method cannot modify input int parameter

Not to sure why the integers lowRange and highRange are not going between these classes.
package guessnumber;
public class GuessNumber
{
static public int computerGenedNumber;
static public int lowRange;
static public int highRange;
static public int playerGuess;
public static void main(String[] args)
{
Input.range(lowRange, highRange);
Rand.number(lowRange, highRange, computerGenedNumber);
Input.guess();
Give.result();
}
}
Next Class:
package guessnumber;
import javax.swing.JOptionPane;
class Input
{
public static void range(int lowRange, int highRange)
{
String rawUserInput;
rawUserInput = JOptionPane.showInputDialog("Please enter the range you wish to guess. (EX: 1-10)", "1-10");
for(int i = 0; i < rawUserInput.length(); i++)
{
if(rawUserInput.charAt(i) == '-')
{
lowRange = Integer.parseInt(rawUserInput.substring(0, i));
highRange = Integer.parseInt(rawUserInput.substring(i + 1, rawUserInput.length()));
}
}
}
static void guess()
{
}
}
And the last relevant one:
package guessnumber;
class Rand
{
static public void number(int lowRange, int highRange, int computerGenedNumber)
{
computerGenedNumber = (int)(Math.random() * (highRange - lowRange) + lowRange);
}
}
The rest of the classes are currently blank so I don't think I need to put them here too.
Here is a simplified piece of code which reproduce your problem, and make sure you understand why it is causing problem and the solution:
class Foo {
public static void square(int a, int result) {
result = a*a;
}
}
class Bar {
public static void main(String[] args) {
int a=2;
int result = 0;
Foo.square(a, result);
System.out.println("result " + result);
}
}
This should be fundamental understanding of Java. Checkout what is the meaning of "pass-by-value"
In brief, the parameter passed in the method is a copy of the argument. Therefore when you are changing the parameter in your method, you are just changing another piece of data, and your change is not reflected to caller.
One way to fix is to change the method and return your result, which looks like:
class Foo {
public static int square(int a) {
return a*a;
}
}
class Bar {
public static void main(String[] args) {
int a=2;
int result = 0;
result = Foo.square(a);
System.out.println("result " + result);
}
}
Another common solution is to pass in a "holder object" as the result. Although the object reference is passed by value, that copy of object reference is still pointing to the same object as caller. I won't go too deep into this as it is less common and you should be able to get the proper way doing so once you have better understanding on how value (including object reference) is passed around.
Parameters are passed "by value" in Java. What that means is that when you call
input.range(lowRange, highRange);
it gives the current values of those variables to input.range, but it doesn't give input.range a way to modify them. In the range method:
public static void range(int lowRange, int highRange)
the parameters lowRange and highRange (which have no connection with the variables in GuessNumber, even though the names are the same) are copies of what you pass in. When you assign lowRange = ... in the method, it changes the copy but has no effect at all on the lowRange and highRange in GuessNumber.
You need to write a range method that returns two values. This needs a little bit of work, but I'd write a Range class that has low and high members, and then change your method to
public static Range range()
That method would have to create a new Range object. I think it's OK for low and high to be public members of Range:
class Range {
public int low;
public int high;
public Range(int low, int high) {
this.low = low;
this.high = high;
}
}
Normally, public data in a class is a bad thing, but for a class whose only purpose is to let a method return multiple values, it's OK in my opinion.

Is it possible to link integers from a method to a class?

I have a quick question out of curiosity...if I declare an integer in one method, for example: i = 1, is it possible for me to take that i and use its value in my main class (or another method)? The following code may be helpful in understanding what I'm asking...of course, the code might not be correct depending on what the answer is.
public class main {
public main() {
int n = 1;
System.out.print(n + i);
}
public number(){
i = 1;
}
}
No you cannot! Not unless you make it an instance variable!
Or actually send it to the function as an argument!
First, let's start simple. All methods that are not constructors require a return type. In other words,
public void number(){
i = 1;
}
would be more proper.
Second: the main method traditionally has a signature of public static void main(String[] args).
Now, on to your question at hand. Let's consider a few cases. I will be breaking a few common coding conventions to get my point across.
Case 1
public void number(){
i = 1;
}
As your code stands now, you will have a compile-time error because i is not ever declared. You could solve this by declaring this somewhere in the class. To access this variable, you will need an object of type Main, which would make your class look like this:
public class Main {
int i;
public static void main(String[] args) {
Main myMain = new Main();
myMain.number();
System.out.print(myMain.i);
}
public void number(){
i = 1;
}
}
Case 2
Let's say you don't want to make i a class variable. You just want it to be a value returned by the function. Your code would then look like this:
public class Main {
public static void main(String[] args) {
Main myMain = new Main();
System.out.print(myMain.number());
}
public int number(){ //the int here means we are returning an int
i = 1;
return i;
}
}
Case 3
Both of the previous cases will print out 1 as their output. But let's try something different.
public class Main {
int i = 0;
public static void main(String[] args) {
Main myMain = new Main();
myMain.number();
System.out.print(myMain.i);
}
public void number(){
int i = 1;
}
}
What do you think the output would be in this case? It's not 1! In this case, our output is 0. Why?
The statement int i = 1; in number(), it creates a new variable, also referred to as i, in the scope of number(). As soon as number() finishes, that variable is wiped out. The original i, declared right under public class Main has not changed. Thus, when we print out myMain.i, its value is 0.
Case 4
One more case, just for fun:
public class Main {
int i = 0;
public static void main(String[] args) {
Main myMain = new Main();
System.out.print(myMain.number());
System.out.print(myMain.i);
}
public int number(){
int i = 1;
return i;
}
}
What will the output of this be? It's 10. Why you ask? Because the i returned by number() is the i in the scope of number() and has a value of 1. myMain's i, however, remains unchanged as in Case 3.
You may use a class-scope field to store you variable in a class object or you can return it from one method or pass it as a parameter to the other. Mind that you will need to call your methods in the right order, which is not the best design possible.
public class main {
int n;
int i;
public main() {
n = 1;
System.out.print(n + i);
}
public number(){
i = 1;
}
}
Yes, create a classmember:
public class Main
{
private int i;
public main() {
int n = 1;
System.out.print(n + i);
number();
System.out.print(n + i);
}
public number(){
i = 1;
}
}
void method(){
int i = 0; //has only method scope and cannot be used outside it
}
void method1(){
i = 1; //cannot do this
}
This is because the scope of i is limited to the method it is declared in.

Call an instance variable when its name is same with the argument variable

I have this code:
class Foo {
int x = 12;
public static void go(final int x) {
System.out.println(x);
}
}
The argument final x and the instance x have the same name. How would I refer to the instance variable x = 12 if I want to use it in the go() method considering its name is the same with the argument variable?
You need to make it static in order to use it within static method:
static int x = 12;
Then you can get a reference to it via the class name:
public static void go(final int x)
{
System.out.println(Foo.x);
}
Or alternatively, create an instance and use it locally:
int x = 12;
public static void go(final int x)
{
Foo f = new Foo();
System.out.println(f.x);
}
Or use instance method, and refer to the instance x with the keyword this:
int x = 12;
public void go(final int x)
{
System.out.println(this.x);
}
this.x points to the instance variable.
In order to refer to an instance variable, you have to be in a real instance: your method should not be static then.

Categories

Resources