Does the final keyword store variables inside methods like static? - java

Newbie to Java here. I'm in the process of porting my iPhone app to Android. From what I've read, the final keyword is pretty much equivalent to static. But does it work the same inside a method?
For example in Objective-C inside a method... static Class aClass = [[aClass alloc] init]; wouldn't be reallocated again and it wouldn't be disposed at the end of the method.
Would something in Java inside a method like... final Class aClass = new aClass(); act the same?

No. Block-local variables go out of scope when the block is exited and are logically (and usually physically) allocated on the stack.

Java isn't really like Objective C in that respect, and final is more akin to const because it indicates a reference may not be altered. In your example, when the block ends the final variable will be eligible for garbage-collection as it is no longer reachable. I think you want a field variable something like
static final aClass aField = new aClass();
Note that Java class names start with a capital letter by convention...
static final MyClass aField = new MyClass();

You are confusing the meaning of Final and Static.
Final means that the value of the variable cannot be changed after its value is initially declared.
Static means a variable can be accessed and changed without needing to instantiate a class beforehand.
Perhaps the following bit of code will make this more clear.
public class SF1 {
static int x;
final int y = 3;
static final int z = 5;
public static void main(String[] args) {
x = 1;
// works fine
SF1 classInstance = new SF1();
classInstance.y = 4;
// will give an error: "The final field main.y cannot be assigned"
z = 6;
// will give an error: "The final field main.z cannot be assigned"
reassignIntValue();
// x now equals 25, even if called from the main method
System.out.println(x);
}
public static void reassignIntValue() {
x = 25;
}
}

You have to declare your variable in class scope so you can able to access it outside of your method.
class ABC{
int a;
public void method(){
a = 10; // initialize your variable or do any operation you want.
}
public static void main(String args[]){
ABC abc = new ABC();
System.out.println(abc.a) // it will print a result
}
}

Related

Can a Variable be initialized inside a Class in Java? What about Static Variable? If yes, then what's the use for Static Block?

In C++(prior to C-11), we needed to initialize the variables outside the Class either through constructors or some methods. What's happens in Java?
Can a Variable be initialized inside a Class in Java?
Yes, like this:
public class MyClass {
private int myVariable = 10;
}
What about Static Variable? If yes, then what's the use for Static Block?
Yes, static variables can be initialized in the class as well:
public class MyClass {
private static int myVariable = 10;
}
Static blocks are used when you want to initialize a static variable, but one line is insufficient. For example:
public class MyClass {
private static HashMap<Integer, Integer> myMap;
static {
myMap = new HashMap<>();
myMap.put(10, 20);
myMap.put(20, 40);
}
}
c++ v/s Java:
Common- both OOP language
difference- c++ is not purely object oriented language, but Java is purely oop language.
Classes are blueprint(like a general map) which defines some attributes/properties(Member variables) and behavior(member functions) of a object of that class.
Class is just a imagination before creation of a object.
Object is real time entity that has physical existence in real world or in simply it's a implementation of class.
Classes in java:
class class_name
{
member variables;
member functions;
};
Ex.
class A
{
int a;
void funct()
{
//body
}
}; //defination is closed with semicolon
but,
classes in java:
ANSWER to ur quesion:
class class_name
{
member variables; //still we define the attributes in class that may be static or non-static
member functions;
};
Significance of static variable:
static variable is alloacated the common memory in ram for all the objects of that class and operation perform by any object on static member is reflected to all other object's static member because of common(same) memory.
significance of static method(functions are called methods in java): static method of a class is a method which is called without creating the object of that class.
In java, main() method is declared as static because after execution of program main() method is called without creating the object of class.
kernal of OS calls the main() method.
Can a Variable be initialized inside a Class in Java?
Yes.
class TestClass {
int abc = 0;
static int def = 1;
}
What about Static Variable?
Yes, you can. Same Example as above.
But this won't be initialized every time an object of the class is created.
TestClass ob1 = new TestClass();
ob1.def = 2; // Always use the class name to access static variables. This is just an example.
TestClass ob2 = new TestClass();
System.out.println(ob2.def); // Output : 2
PS : Always use the class name to access static variables. This is just an example.
What's the use for Static Block?
If the initialization of static variables is complex, then you can create a static block and initialize those variables there. Here is a good reference for the same.
class TestClass {
int abc = 0;
static int def = 1;
static {
int x = 100;
int y = 20;
def = x - y + 10;
}
}
If you wat to initialize the variable you can create something like
public class Animal
{
int age = 21;
static int roll = 23;
}
But remember the difference between instance variables and static variables,
int age - this variable is created for each object you create
static int roll - this variable is created only once and is one for every other object.

How to get a value in an object in Java?

Let's say I have something like this :
public class obj{
public int x;
public obj(int x){
this.x = x;
}
}
and this :
public class main{
obj o = new obj(1);
public static void main(String[] args){
//get the value of OBJ
//add 1 to the value got from above(let's just say I wanted to. no reason why)
}
}
is there a possible way to get the value of the obj's x value without changing the x to static? And make it so that you can change it? when I try to do something like this, it always says to change the x to static. why? I know this may be a weird question but i just wanted to know :)
You need to change your object to static first since you are accessing it directly from static main.
private static obj o = new obj(1);
// You can get the value of `x` from `o` as follows:
int x = o.x;
// You can increment the value in the object `o` as follows:
o.x++;
First of all, your class declaration is wrong. You don't use parenthesis in class declaration.
Also, in Java you write class names big. (The class Object already exists, don't make a class "Obj" because it would mean the same and is an abbreviation.)
public class MyObject {
public int x;
public MyObject(int x){
this.x = x;
}
}
public class Main {
MyObject myInstance = new MyObject(1);
public static void main(String[] args){
// You can just do ++ behind the variable. This adds +1.
myInstance.x++;
// If you want to get the value of the (public) variable x:
int temp = myInstance.x;
}
}
Yes you can get it by using
o.x
It is not telling you to change x to static. It is telling you to make o to static. o is non-static and cannot be used in the static main method.
Non-static instances can't be assessed in static method directly. Since o is an instance variable rather than static variable, you will need to create an instance of Main to access it's non-static variable.
public class Main {
Obj o = new Obj(1);
public static void main(String[] args){
Main main = new Main();
main.o.x += 1;
}
}

Can an instance of a class modify static / class variable?

class Person {
public static int age = 10;
}
public class Application {
public static void main(String[] args) {
Person p = new Person();
p.age = 100;
System.out.println(Person.age);
Person.age = 22;
System.out.println(p.age);
}
}
I got 100 and 22 printed. Was I wrong in assuming that instances of a class cannot access/modify class/static variables.
I think the part your confused by is the meaning of static. the age variable in class Person will be shared across all instances of Person, and can be accessed with no instance at all via:
Person.age = 100;
Changing it for any instance:
Person p = new Person();
p.age = 100;
changes it for everyone, and is the same as calling
Person.age = 100;
Changing it in a non static way, meaning via some instance only makes the code misleading by making people think they are changing an instance variable at first glance. You will get a compiler warning about this.
Yes, they can. From the docs:
Fields that have the static modifier in their declaration are called static fields or class variables. They are associated with the class, rather than with any object. Every instance of the class shares a class variable, which is in one fixed location in memory. Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class
Of course an instance of a class can access and modify a static field, if it's accessible to that scope.
What cannot happen is a static statement/method body modifying an instance it does not "know about", e.g. a static method using this.
Example
public class Main {
private static int meh = 0;
int blah = 0;
public static void main(String[] args) {
// ugly but compiles fine
// equivalent to Main.meh = 1
meh = 1;
// Will NOT compile - main method is static,
// references instance field "blah" out of scope
// Equivalent to this.blah = 1
blah = 1;
}
}

Do final variables need to be given a value immediately after declaring them

Is it possible to assign a value to a final variable anywhere else in the program? Or is it mandatory that they be assigned a value upon creation?
class TestClass() {
//this won't compile but is it possible to assign str a value anywhere else in the program?
public static final String str;
}
You need to assign a value when it's declared - in the constructor if it's not static, in the static initializer block if it is. Once you set the value, it can't be modified.
Do it like this:
public class FinalTest {
private static final String CONSTANT;
private final String value;
static {
CONSTANT = "Hello";
}
public static void main(String [] args) {
FinalTest ft = ((args.length > 0) ? new FinalTest(args[0]) : new FinalTest(CONSTANT));
System.out.println(ft);
}
public FinalTest(String value) {
this.value = value;
}
public String toString() { return this.value; }
}
Local variables
A final variable needs to be assigned a value exactly once before it is accessed. This means that if it's never assigned a value and never accessed, the compiler won't complain.
void foo() {
final int a; // Never assigned, but never accessed either, so no problem
final int b = 7;
System.out.println("b is " + b);
// System.out.println("a is " + a);
// Uncommenting the above line would cause a compile error
}
Static fields
A similar logic applies to final static fields, except it's assumed that they will be accessed at some point, so they must be initialized either on the definition line or in a static initializer block.
Here's what the Java tutorial has to say about static initialization blocks:
This works well when the initialization value is available and the initialization can be put on one line. However, this form of initialization has limitations because of its simplicity. If initialization requires some logic (for example, error handling or a for loop to fill a complex array), simple assignment is inadequate. Instance variables can be initialized in constructors, where error handling or other logic can be used. To provide the same capability for class variables, the Java programming language includes static initialization blocks.
Note: It is not necessary to declare fields at the beginning of the class definition, although this is the most common practice. It is only necessary that they be declared and initialized before they are used.
Instance fields
While we're at it, a final instance (non-static) field must be assigned a value exactly once by the time the instance initialization is complete. This means there are three places where you can initialize one (but you must pick one):
1. Definition line:
// For when you know the answer
class Foo {
final int theAnswer = 42;
}
2. Constructor:
// For when you need to have the answer passed in
class Foo {
final int theAnswer;
Foo(int answer) {
theAnswer = answer;
}
}
// Or for when you need to do some computation
class Bar {
static final int ANSWER_COUNT = 10;
final int[] answers;
Foo() {
answers = new int[ANSWER_COUNT];
for (int i = 0; i < ANSWER_COUNT; i++) {
answers[i] = i;
}
}
3. Initializer block:
// For when you need to do some computation and have many constructors
class Bar {
static final int ANSWER_COUNT = 10;
final int[] answers;
{
answers = new int[ANSWER_COUNT];
for (int i = 0; i < ANSWER_COUNT; i++) {
answers[i] = i;
}
}
// I have many constructors and don't want to copy-paste
// the initialization logic above to all of them
Bar() { ... }
Bar(int i) { ... }
Bar(String blah) { ... }
}
From the same page in the tutorial, regarding initializer blocks:
The Java compiler copies initializer blocks into every constructor. Therefore, this approach can be used to share a block of code between multiple constructors.
In the code you posted, the field is static so it could be given a value from within a static initialization block:
static {
str = "my string";
}
For non-static fields, they can either be initialized in the constructor, or in an instance initializer block:
class TestClass {
private final String str;
{
str = "my string";
}
TestClass() {
}
}

Static methods and static fields in Java behave somewhat in a strange way

By convention, a static method specifically in Java can have access only to static fields or other static methods. The following simple code snippet however appears to violate the convention. Let's consider the following simple code snippet in Java.
class Super
{
protected static int x;
protected static int y;
public Super(int x, int y)
{
Super.x=x;
Super.y=y;
}
public static int sum()
{
return(x+y);
}
}
final class Sub extends Super
{
public static int temp=100;
public Sub(int x, int y)
{
super(x, y);
}
public void concreateMethod()
{
System.out.println("\nInstance variable x = "+x);
System.out.println("Instance variable y = "+y);
}
}
final public class Main
{
public static void main(String[] args)
{
Sub s=new Sub(10, 5);
System.out.println("\nAssociating with object x = "+s.x);
System.out.println("Associating with object y = "+s.y);
System.out.println("\nAssociating with class name x = "+Sub.x);
System.out.println("Associating with class name y = "+Sub.y);
System.out.println("\nSummation (Associating with object) = "+s.sum());
System.out.println("Summation (Associating with class name) = "+Sub.sum());
System.out.println("\nAssociating with class name temp = "+Sub.temp);
System.out.println("Associating with object temp = = "+s.temp);
System.out.println("\nConcreate method called.");
s.concreateMethod();
}
}
The above code produces the following output with the respective statements.
Associating with object x = 10
Associating with object y = 5
Associating with class name x = 10
Associating with class name y = 5
Summation (Associating with object) = 15
Summation (Associating with class name) = 15
Associating with class name temp = 100
Associating with object temp = = 100
Concreate method called.
Instance variable x = 10
Instance variable y = 5
The static fields s and x are being accessed through the following statements within the main() method using the object of the Sub class, though they are declared as static in the super class Super.
Sub s=new Sub(10, 5);
System.out.println("\nAssociating with object x = "+s.x);
System.out.println("Associating with object y = "+s.y);
The following statements of course, have no doubt.
System.out.println("\nAssociating with class name x = "+Sub.x);
System.out.println("Associating with class name y = "+Sub.y);
Since x and y are static, they can certainly be accessed in this way.
The same is the method call, observe the following statements.
Sub s=new Sub(10, 5);
System.out.println("\nSummation (Associating with object) = "+s.sum());
System.out.println("Summation (Associating with class name) = "+Sub.sum());
Both of the ways, the static method sum() is being accessed using the object of the class Super and also using the class name Sub.
Again the similar case with the static field temp declared within the Sub class
System.out.println("\nAssociating with class name temp = "+Sub.temp);
System.out.println("Associating with object temp = = "+s.temp);
The static field temp is being accessed in both the ways.
Why is this happening here?
Basically it's a flaw in the design of Java IMO which allows static members (methods and fields) to be referenced as if they were instance members. This can be very confusing in code like this:
Thread newThread = new Thread(runnable);
newThread.start();
newThread.sleep(1000);
That looks like it's sending the new thread to sleep, but it actually compiles down into code like this:
Thread newThread = new Thread(runnable);
newThread.start();
Thread.sleep(1000);
because sleep is a static method which only ever makes the current thread sleep.
Indeed, the variable isn't even checked for non-nullity (any more; it used to be, I believe):
Thread t = null;
t.sleep(1000);
Some IDEs can be configured to issue a warning or error for code like this - you shouldn't do it, as it hurts readability. (This is one of the flaws which was corrected by C#...)
There is no problem there. Static methods can only access static fields and call other static methods as you have stated. Nothing in your examples does otherwise.
Non-static methods can access both static and non-static methods and fields. Again, none of your examples violate that.
The Sub.temp and s.temp are equivalent and you can use both, it means the same. But 1st is better one because suggests it's a static field.
a static method specifically in Java can have access only to static fields or other static methods declared within the same class
Or its superclass.
I don't see any violation here, you can access static fields/methods via its concrete object or class name. both refer to the same thing.
Where do you see a non-static field or method being accessed by static code? Everything seems perfectly fine to me.
Perhaps what's confusing you is that static fields and methods can be accessed through instances as well as through the class name? It's certainly a big ugly and many consider it bad design, but that's all.

Categories