How do I access the method variable having the same name as the inner class member instance or method local variable of the inner class?
class A{
int a = 10; //1
public void someMethodA(){
final int a = 20; //2
class B{
int a = 30; //3
public void someMethodB(){
int a = 40; //4
System.out.println("a = "+a); //access 4
System.out.println("a = "+this.a); //access 3
System.out.println("a = "+A.this.a); //access 1
System.out.println(?????); //how do I access value of a i.e 2
}
}
}
}
No. You can't do that. The reason being, the variable a in position 2 is a local variable, which can only be accessed with it's simple name, in the enclosing scope. From JLS §6.4:
A local variable (§14.4), formal parameter (§8.4.1), exception parameter (§14.20), and local class (§14.3) can only be referred to using a simple name (§6.2), not a qualified name (§6.6).
Now, this clears that you can only access that variable with just a. But, you have another variable in method local class B which shadows that local variable a in position 2, which is again shadowed by local variable in position 4.
Now in print statement, a would access the variable from nearmost enclosing scope, that is local variable at position 4. If you remove that variable, it will print the variable at position 3. And then if you remove it, it will print the variable at position 2.
So, the point is, there is no way to access the local variable a at position 2, because that is shadowed.
that code will never output those statements, here is an example from Sun that should explain things :
public class ShadowTest {
public int x = 0;
class FirstLevel {
public int x = 1;
void methodInFirstLevel(int x) {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
}
}
public static void main(String... args) {
ShadowTest st = new ShadowTest();
ShadowTest.FirstLevel fl = st.new FirstLevel();
fl.methodInFirstLevel(23);
}
}
I am not sure, what you actually mean, but you access a class member with the same name as a local variable with the same name like this:
public class A
{
int a = 10;
public void someMethodA()
{
int a = 5;
this.a = 20; //change the member a from 10 to 20
a = 30; // changes the local variable, which is only known in this method to 30
}
}
Typically this pattern is used in constructors, to name the params the same as member variables, for example:
class Foo
{
private int bar = 10;
private string fooBar = 20;
public Foo(int bar, string fooBar)
{
this.bar = bar;
this.fooBar = fooBar;
}
}
Related
What is the internal reason due to which within method local inner class we can only access final or effectively final local variables of the method in which that inner class is declared?
Please see below example.
class Test{
int i = 10;
static int j = 20;
public void m1(){
int k = 30;
//k=40;
final int m = 40;
class Inner{
public void m2(){
System.out.println("value of i = " + i + " value of j = " + j + " value of k = " + k + " value of m = " + m);
}
}
Inner i = new Inner();
i.m2();
}
public static void main(String[] args){
Test t = new Test();
t.m1();
}
}
If I try to change the value of variable k (line commented in source code), then there will be compiler error stating "local variables referenced from an inner class must be final or effectively final"
Also in java versions lower than 1.8, local variables must be explicitly defined as final if you want to access that variable within method local inner class.
I've made a class named 'Car'and I have this code.
Car c=new Car(), yourCar;
and I don't know what 'yourCar' means
Is is same asCar myCar = new Car(); Car yourCar = new Car();
?
I can't understand after the comma.
package ex2_datatypecasting02;
class Car{
String name = "car";
String print() {
return name;
}
}
class Bus extends Car{
String name = "bus";
String print() {
return name;
}
}
public class CastingExam {
public static void main(String[] args) {
Car myCar = new Car(),yourCar;
Bus myBus = new Bus(),yourBus;
System.out.println(myCar.print());
System.out.println(myBus.print());
yourCar = myBus;
yourBus = (Bus)yourCar;
System.out.println(yourBus.print());
}
}
You can declare multiple variables of the same type on one line by separating them with a comma (,). Like:
//declare three integers
int x, y, z;
which is equivalent to:
int x; // declare x
int y; // declare y
int z; // declare z
So here I have declared three integers, but I have not initialized them. You can also initialize one or more of them, like:
//declare three integers, initialize two of them
int x = 1, y, z = 4;
// ^ ^ initialized
which is equivalent to:
int x = 1; // declare and initialize x
int y; // declare y
int z = 4; // declare and initialize z
Here we have declared three variables, and initializes x and z with 1 and 4 respectively.
So the statement declares two Car variables: c and yourCar, and c is initialized with a new car, yourCar is not.
As Willem well explained, this statement :
Car myCar = new Car(),yourCar;
is valid and allows to declare two Car variables but initializes only one of them : myCar.
yourCar is indeed null here.
I would like to add that this way of doing spares you a line but is really error prone.
To get a better readability of your code, you should declare each variable on a distinct line :
Car myCar = new Car();
Car yourCar;
It produces the same result but it is much clearer.
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
To be honest i am really struggling with Java, i am trying to access an array from another class. I believe i have created the array in this code
public class aff_array {
String name;
public static void main (String[] args) {
int z = 3; //total no of affirmations
int x = 1;
aff_array[] afz = new aff_array[z]; //dim
while ( x < z ) {
afz[x] = new aff_array(); // create objects for array
x = x + 1;
}
afz[1].name = "i am the best";
afz[2].name = "you are the rest";
}
but i am really having trouble trying to figure out how i access afz[1].name for example, from another class. This is probably basic but i am really struggling..
You cannot access it from another class as long as it is created as an automatic variable (in other terms, local variable). In the above code, your "afz" construct will be visible only inside the main method (and can be used only after it's instatiation). To make it visible for other classes you can define it as an instance variable. I.e:
public class aff_array {
String name;
aff_array[] afz;
public static void main (String[] args) {
int z = 3; //total no of affirmations
int x = 1;
afz = new aff_array[z]; //dim
First, you should define it as private, and create a getter method (this is a common practice, to respect encapsulation), and then get it on the other class simply calling this method.
You can access public instance variable "name" of aff_array class
//this will print value of instance variable name
System.out.println(afz[1].name);
//If you want to modify the value of variable
afz[1].name = "modified name";
However this is not recommended. Protect your instance variable with private access modifier and access it using public getter, setter methods.
Example:
public class aff_array {
private String name;
public String getName()
{
return this.name;
}
public void setName(String new_name)
{
//You can add some validations here
this.name = new_name;
}
public static void main (String[] args) {
int z = 3; //total no of affirmations
int x = 1;
aff_array[] afz = new aff_array[z]; //dim
while ( x < z ) {
afz[x] = new aff_array(); // create objects for array
x = x + 1;
}
//To print name
System.out.println(afz[1].getName());
//to set new value to name
afz[1].setName("i am the best");
afz[2].setName("you are the rest");
}
So i have tried to add getters and it looks like this
public class aff_array {
String name;
aff_array[] afz;
public aff_array[] getAfz() {
return afz;
}
public String getName() {
return name;
}
public static void main (String[] args) {
int z = 3; //total no of affirmations
int x = 1;
aff_array[] afz = new aff_array[z]; //dim
while ( x < z ) {
afz[x] = new aff_array(); // create objects for array
x = x + 1;
}
afz[1].name = "i am the best";
afz[2].name = "you are the rest";
}
This is the other class and where i want the array value to replace aff_array.class.getName() with aff_array[] getAfz() but i dont know how to do it or reference afz(1) for example (getName is working)
public void onReceive(Context context, Intent intent)
{
setNotification(context, aff_array.class.getName());
WakeLocker.acquire(context);
Toast.makeText(context,"One shot alarm received. No more toasts will be shown.", Toast.LENGTH_SHORT).show();
WakeLocker.release();
}
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.