Protected variable in main method - java

I declared my local variable to protected that is the same name with other general variable.
My code:
public class jc8 {
private int x = 8;
public static void main(String[] args) {
protected int x = 5; // compile time ERROR
}
}
why ?

You can not use the protected key word inside a method block. This is to modify the access of members, not of local variables. Think about it. your local variable's scope is only the main method. It is, by definition, private to that method.
Example
protected int x = 10;
public static void main(String[] args)
{
// Valid
}
This will allow subclasses of your class to have access to x.

"public", "protected" or "private" are visibility modifiers that can be applied to class members not to local variables.
But more important than that, what do you try to accomplish with this definition?, what its the meaning in your head of a local variable to be protected?, think about this and try to understand "why" this is not possible in java.

o Protected Accessibilty:
Indicates that a member can be accessed from any class in the same package and from the child classes from other packages. A keyword “protected” is used to represent protected accessibility before the data type of a member declaration.
Example:
protected int y;
protected void method(){}
so you can not use protected inside a block of code .you need to declare it outside of block of code
you declared
public static void main(String[] args) {
protected int x = 5; // compile time ERROR
}
Right way is
protected int x = 5;
public static void main(String[] args) {
// compile time ERROR
}

The local variable not modified.
Why your are trying to do it?
Their scope is between method braces.

Related

Declaring a static variable in a non-static class in Java

I am new to java. I am currently reading some articles about static variables. When I am trying to implement my learnings, I encountered a problem about static variables. Here is the first code sample.
public class Human {
// in Human.java
public static int population = 0;
public static void main(String[] argv) {
System.out.println(population);
}
}
This code works fine and the outcome is 0.
But for the following code, I wasn't allow to compile it.
public class Human {
// in Human.java
public class Charlie extends Human {
public static int number = 0;
}
public static void main(String[] argv) {
System.out.println(new Human().new Charlie().number);
}
}
An error occurred: The field number cannot be declared static in a non-static inner type, unless initialized with a constant expression
I am confused with this situation. For the first code sample, my Human class is non-static and I was allowed to declare a static variable inside it. How come I can't do the same for my second code sample.
Any help would be appreciated. Thanks. :)
Try with public static final int number = 0; because Java does not let you define non-final static fields inside function-local inner classes. Only top-level classes and static nested classes are allowed to have non-final static fields.
From the JLS section 8.1.3:
Inner classes may not declare static members, unless they are constant variables (§4.12.4), or a compile-time error occurs.
Other way to make inner class static and access it
public class Human {
// in Human.java
public static class Charlie extends Human {
public static int number = 0;
}
public static void main(String[] argv) {
System.out.println(new Human.Charlie().number);
}
}

How to use static method variables in other static methods in Java?

I declare and initialize a variable in a static method. How can I use this variable in another static method? I have tried to call the variable by the static method's name.
How do I use a variable that is declared and initialized in one static
method and use it in another static method?
You can't . Cause the variable's scope belongs only to the method where was declared.
An alternative is making the variable as a class variable , then all methods can use this variable.
public class Test {
private static int variable;
public static void method1(){
variable++;
}
public static void method2(){
variable--;
}
}
Take care if multiple threads access to these methods.
you can't because if you declaer in one method is this varible local, you must declare as global varibl and initilized in method.
you have to have the variable outside of the method and make it static too.
ex:
public static int accessMeOutside = 0;
public static void methodOne(){
accessMeOutside = 1;
}
public static void methodTwo(){
if(accessMeOutside == 1)
accessMeOutside = 2;
}
if you call methodOne, then methodTwo, accessMeOutside will end up correctly being set as 2.

Variable visibility in Java

In the following code, why can't I see the variable "i" from another thread?
public class Main {
public static void main(String[] args) {
int i = 0;
new Thread(new Runnable() {
#Override
public void run() {
System.out.println(i);
}
}).start();
}
}
And why can I see it in the code below?
public class Main {
int i = 0;
public static void main(String[] args) {
new Main().method();
}
private void method() {
new Thread(new Runnable() {
#Override
public void run() {
i = 1;
}
}).start();
}
}
From docs:
As with instance methods and variables, an inner class is associated
with an instance of its enclosing class and has direct access to that
object's methods and fields.
Now taking the second example first, when i is declared in parent class, the inner class can access it, because inner class has access to entire parent object. And i is correctly referenced as Main.this.i from inner class.Now compiler secretly makes a copy of this.i inside inner class. this never changes inside the object, this.i will point to correct object for both inner and outer class. Compiler is happy.
In first example, i is not part of parent class, its declared inside a method hence its reference is now on stack, and not on heap. (In this case, i doesn't get to live on that big outer circle shown in above diagram). Now compiler must secretly make a copy of i inside inner class as well. But it is afraid that method's i may change on stack. Compiler can't use outer class connection to get to i here, and it can't bother to copy i reference from stack every time it changes. So, it is decided that you must make the method's i reference unchangeable, or in other words, final.
The obscure secret tricks Java plays so that you can access outer fields from inner classes is explained in detail here: http://techtracer.com/2008/04/14/mystery-of-accessibility-in-local-inner-classes/
and discussed more "why's" here : http://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg04044.html
tl;dr: Instance fields are directly accessible by inner classes, local fields must be made final to be accessible by a inner class.
Java only allows you to access the values of local variables that are declared final in anonymous classes. No writing is allowed. The rationale for this is because the function scope might be (and indeed in this case is) exited while the variable is accessible from within the inner class, the value is actually cached within the anonymous class instances. To avoid confusion and make JIT work, these variables are allowed to be final only. Notice that only the primitive value, or the reference cannot be modified, but anything contained within a referenced object can still be modified.
In the second case it is an instance variable accessible to the thread. Note that i = 1 stands now for Main.this.i; the Main.this. part being implicit.
In the first program you can "see" variable i, but not access it, because it is not declared final. Only member variables and final local variables declared before creating an instance of your anonymous class can be accessed:
public class Main {
public static void main(String[] args) {
final int i = 123; // Make the variable final
new Thread(new Runnable() {
#Override
public void run() {
System.out.println(i); // Now it works, but you cannot assign it
}
}).start();
}
}
Demo on ideone.
Making your variable static would work as well:
public class Main {
private static int i = 321;
public static void main (String[] args) throws java.lang.Exception
{
new Thread(new Runnable() {
#Override
public void run() {
System.out.println(i); // Now it works, but you cannot assign it
}
}).start();
}
}
Demo.

Getting access to variable inside function

I am positive this has probably been answered many many times but I do not know the words to search for to find the answer. So here is the question
I'm using java and I have
int my_var = 3;
thing.myListener(new Listener() {
public void onStart(int posistion) {
my_var <-- I want to get access to my_var
}
});
How do I get access to my_var inside the onStart function. Also what is this type of problem called? Thanks!
You have to make it final. This is an anonymous inner class.
final int my_var = 3;
I would suggest using global variables. Here is an example:
A simple way to utilize "global" variables in Java is to define a class Global with the desired variables as static members of it:
public class Global {
public static int x = 37;
public static String s = "aaa";
}
Such members can be accessed by saying:
public class test {
public static void main(String args[])
{
Global.x = Global.x + 100;
Global.s = "bbb";
}
}
Is that what you are looking for?

Java instance variable declare and Initialize in two statements

Hi I'm having problem with initialization in java, following code give me compile error called : expected instanceInt = 100; but already I have declared it. If these things relate with stack and heap stuff please explain with simple terms and I'm newbie to java and I have no advanced knowledge on those area
public class Init {
int instanceInt;
instanceInt = 100;
public static void main(String[] args) {
int localInt;
u = 9000;
}
}
You can't use statements in the middle of your class. It have to be either in a block or in the same line as your declaration.
The usual ways to do what you want are those :
The initialization during the declaration
public class MyClass{
private int i = 0;
}
Usually it's a good idea if you want to define the default value for your field.
The initialization in the constructor block
public class MyClass{
private int i;
public MyClass(){
this.i = 0;
}
}
This block can be used if you want to have some logic (if/loops) during the initialization of your field. The problem with it is that either your constructors will call one each other, or they'll all have basically the same content.
In your case I think this is the best way to go.
The initialization in a method block
public class MyClass{
private int i;
public void setI(int i){
this.i = i;
}
}
It's not really an initialization but you can set your value whenever you want.
The initialization in an instance initializer block
public class MyClass{
private int i;
{
i = 0;
}
}
This way is used when the constructor isn't enough (see comments on the constructor block) but usually developers tend to avoid this form.
Resources :
JLS - Instance Initializers
On the same topic :
Use of Initializers vs Constructors in Java
How is an instance initializer different from a constructor?
Bonus :
What does this code ?
public class MyClass {
public MyClass() {
System.out.println("1 - Constructor with no parameters");
}
{
System.out.println("2 - Initializer block");
}
public MyClass(int i) {
this();
System.out.println("3 - Constructor with parameters");
}
static {
System.out.println("4 - Static initalizer block");
}
public static void main(String... args) {
System.out.println("5 - Main method");
new MyClass(0);
}
}
The answer
Put it in an initializer block.
public class Init {
int instanceInt;
{
instanceInt = 100;
}
public static void main(String[] args) {
int localInt;
int u = 9000;
}
}
Or simply initialize while declaring it:
public class Init {
int instanceInt = 100;
public static void main(String[] args) {
int localInt;
int u = 9000;
}
}
References:
Java Tutorial - Initializing Fields
Java - Initializer Block
You can not have a separate statement to assign values to class members in the declaration area. You have to do this from a function, typically a class method.
For your case, consider doing the assignment as soon as you declare.
You need to do :
int instanceInt = 100;
If it was static you could initialize in a static block.
According to the Java Language Specification:
A class body may contain declarations
of members of the class, that is,
fields (§8.3), classes (§8.5),
interfaces (§8.5) and methods (§8.4).
A class body may also contain instance
initializers (§8.6), static
initializers (§8.7), and declarations
of constructors (§8.8) for the class.
However, the statement
instanceInt = 100;
is none of those things, therefore it is not allowed as part of a class body. What you need to do is this:
int instanceInt = 100;
This is allowed because it is a field declaration that includes a variable initializer.

Categories