Why cant instance variable be initialised in class? - java

This is my code:
public class MyClass {
int x;
MyClass m1 = new MyClass();
m1.x=10;
}
Why does line m1.x=10; result in error?

if you want to assign value to the variable x,
the line initializes it should be placed in specific method like below.
did you intend to do this?
public class MyClass
{
int x;
public static void main(String[] args)
{
MyClass m1 = new MyClass();
m1.x = 10;
}
}

Use instance initialization block:
public class MyClass {
int x; // define x variable
MyClass m1 = new MyClass(); // initialize m1 variable
{
m1.x=10; // assign 10 to m1.x (this is assignment statement)
}
}
Out of block you can do only defining and initializing variables, not assignment statement.

There are two errors in your code:
MyClass m1 = new MyClass();
This is an infinite recursion.
m1.x=10;
This is a statement, and as such should be within a method or constructor, not the class body.

The problem here is the code m1.x=10;
This line shows an operation or behavior which is only permissible within a block of code.
Valid Code for this operation.
public class MyClass {
int x;
public void assignOperation() {
this.x = 10;
}
public static void main( String[] args ) {
MyClass myClass = new MyClass();
myClass.assignOperation();
System.out.println( "Assigned value is " + this.x )
}
}
Another valid example outside of a method but within the class body will be :
public class MyClass {
static int x;
static {
x = 10;
}
public static void main( String[] args ) {
System.out.println( "Assigned value is " + x )
}
}
making variable x static doesn't need us initialize an object of the class MyClass.

Related

How do I execute the function public method declared inside a class which is in turn inside a private method?

So, I want to execute the sum() of the following block of code:
import java.lang.reflect.Method;
public class LocalOuterClass { // start of outer
private int x = 10;
private Object run() { //start of inner
class LocalInnerClass {
private int y = 20;
public void sum() {
System.out.println(x+y);
}
} //end of inner
LocalInnerClass lc = new LocalInnerClass();
//lc.sum();
return lc;
}
public static void main(String[] args) {
LocalOuterClass Loc = new LocalOuterClass();
Object obj = Loc.run();
System.out.println(obj.getClass());
Method[] methods = obj.getClass().getMethods();
for (Method method : methods) {
String MethodName = method.getName();
System.out.println("Name of the method: "+ MethodName);
}
}
} //end of outer
When I do lc.sum(), the sum() is correctly executed. But when I'm returning an object of the inner class to the main() and try to execute sum(), it gives a compiler error. Doing getClass().getMethods() on the object does print sum() as one of the methods. What should I do to execute the sum() inside main()?
You have to change return type to LocalInnerClass and move LocalInnerClass out of the method:
public class LocalOuterClass {
private int x = 10;
private class LocalInnerClass {
private int y = 20;
public void sum() {
System.out.println(x + y);
}
}
private LocalInnerClass run() {
LocalInnerClass lc = new LocalInnerClass();
//lc.sum();
return lc;
}
public static void main(String[] args) {
LocalOuterClass Loc = new LocalOuterClass();
LocalInnerClass obj = Loc.run();
obj.sum(); // it works!
// ...
}
}
The problem is, that the whole LocalInnerClass is not known to your main-method. It does not help, that it has a public method, if the whole type is unknown. You need to refactor your code in order to change that.
Actually your method run currently returns a value of type Object and you'd need to return a value of type LocalInnerClass, however this is not possible due to type visibility.
There are basically two options you have. One is to move the whole LocalInnerClass to a location that is visible to main (like oleg.cherednik suggested):
class LocalOuterClass {
private int x = 10;
private LocalInnerClass run() { // now we can retun `LocalInnerClass`
return new LocalInnerClass();
}
public static void main(String[] args) {
new LocalOuterClass().run().sum(); // works!
}
private class LocalInnerClass {
private int y = 20;
public void sum() {
System.out.println(x+y);
}
}
}
Another option is to implement/extend a different type that has sum, e.g. like this:
class LocalOuterClass {
private int x = 10;
private Summable run() { //start of inner
class LocalInnerClass implements Summable {
private int y = 20;
public void sum() {
System.out.println(x+y);
}
}
return new LocalInnerClass();
}
public static void main(String[] args) {
new LocalOuterClass().run().sum(); // works as well
}
private interface Summable {
void sum();
}
}
With this interface-option the type LocalInnerClass is still not visible to anyone outside your run-method, however the Summable-interface is and since your LocalInnerClass implements Summable you can return a value of that type.

Doesn't this defy the rules of static variables?

I have declared a static variable and am changing its value through a non-static method by invoking it in the Initializer block which will be invoked every time an object is instantiated. Why does this not give me run time or compile time error?
public class FinalKeyWord {
final int age;
static int name;
{
ran();
displayName();
}
public FinalKeyWord() {
this.age = 10;
}
public FinalKeyWord(int a){
this.age = a;
}
void ran(){
Random r = new Random();
int rand = r.nextInt(6);
System.out.println(rand);
name = rand;
}
public void displayAge() {
System.out.println("This is final " + age);
}
public void displayName() {
System.out.println("This is static " + name);
}
public static void main(String[] args) {
FinalKeyWord a = new FinalKeyWord();
//a.displayAge();
//a.displayName();
FinalKeyWord a2 = new FinalKeyWord(35);
//a2.displayName();
}
}
Output:
This is static 2 \n
This is is static 3
a variable being static doesn't mean that you can't change its value later, it means that its allocated once in memory for all instances of the class its in, so whenever you create an new object it will point to the same block in memory for this variable unlike normal variables or instance variables where a new block in memory will be reserved for this variable whenever a new object of this class is created.
From Java Documentation/Tutorials,
Instance methods can access class variables and class methods directly.
So this is perfectly legal,
public class FinalKeyWord {
static int a = 5;
void change() {
a= 10;
}
public static void main(String[] args) {
FinalKeyWord obj = new FinalKeyWord();
System.out.println(a);
obj.change();
System.out.println(a);
}
}
And will print,
5
10

How to override instance variables/methods in main?

I want to access the instance variable x in the super class.
I can't find a syntax for it. Is this even possible?
public class SuperBoss {
int x = 10;
}
public class Boss extends SuperBoss {
int x = 2;
public static void main ( String[] args ) {
Boss b = new Boss();
System.out.println(b.x); //prints out 2, I want it to print out 10
}
I've been trying to use the keyword "super" with no success.
It prints out 2 because your declaration of int x = 2 in Boss is hiding the declaration of x in SuperBoss
Normally you would use the super keyword to explicitly access public fields of the superclass, this however won't work from the static context of the main method. You can define a small helper function that will get you the value of the superclass's x
public class Boss extends SuperBoss {
int x = 2;
public int getSuperX() {
return super.x;
}
public static void main ( String[] args ) {
Boss b = new Boss();
System.out.println(b.getSuperX()); //prints out 2, I want it to print out 10
}
}
As far as I can tell (and I should probably look in the JLS for the details), it is legal to access a shadowed non-private field with super, but only from within an instance method. So you could do this:
public class Boss extends SuperBoss {
int x = 2;
int getSuperX() {
return super.x;
}
public static void main (String[] args) {
Boss b = new Boss();
System.out.println(b.getSuperX());
}
}
Add getSuperX() method in your Boss class:
public class Boss extends SuperBoss {
int x = 2;
public int getSuperX() {
return super.x;
}
public static void main(String[] args) {
Boss b = new Boss();
System.out.println(b.getSuperX());
}
}
Yes, there is a way. Fields have compile-time binding. What you need is a cast to SuperBoss:
public class SuperBoss {
int x = 10;
}
public class Boss extends SuperBoss {
int x = 2;
public static void main ( String[] args ) {
Boss b = new Boss();
System.out.println(((SuperBoss)b).x);
}
}
To do what you want, you need to declare x as protected in the superclass, and not attempt to override it in the subclass:
public class SuperBoss {
protected int x = 10;
}
public class Boss extends SuperBoss {
// int x = 2;
public static void main ( String[] args ) {
Boss b = new Boss();
System.out.println(b.x);
}
}
In practice, however, there is little need for protected data. It can cause almost as many problems as public data. Better is:
public class SuperBoss {
private int x = 10;
protected int getX() {
return x;
}
}
public class Boss extends SuperBoss {
// int x = 2;
public static void main ( String[] args ) {
Boss b = new Boss();
System.out.println(b.getX());
}
}
What is going on is that the instance variable of Boss is hiding the instance variable of the same name in SuperBoss. You can temporarily cast your instance to the supertype class:
public static void main ( String[] args ) {
Boss boss = new Boss();
SuperBoss superBoss = boss;
System.out.println(boss.x); //prints 2
System.out.println(superBoss.x); //prints 10
}
This is not recommended. For encapsulation reasons, your instance variables should not be visible, ie. should be private/protected. And probably should not have the same name as variables in parent classes.

Accessing variable from an inner class - getting null pointer exception

i want to access the arr variable from inside the inner class method MyMethod. When i try to print it from there i end up getting a null pointer exception.
public class MyClass{
String[] arr;
MyClass my;
public MyClass(){
my = new MyClass();
}
public class MyInner {
public void MyMethod() {
// I need to access 'my.arr' from here how can i do it.
}
}
public static void main(String[] args) {
String[] n={"ddd","f"};
my.arr=n;
}
}
You can use just arr. However until you set it to something it will be null
BTW: Your my = new MyClass() will blow up as it will create objects until it stack overflows.
You haven't initialized it yet, so the reference is null. Initialize it in your constructor for example, and you will have access to the variable via your inner class.
public class MyClass {
String[] arr;
public MyClass (String[] a_arr) {
arr = a_arr;
}
public class MyInner {
public void MyMethod () {
// I need to access 'my.arr' from here how can i do it.
}
}
public static void main (String[] args) {
String[] n= {"ddd","f"};
MyClass myClass = new MyClass (n);
}
}
Well, for starters in your main method you never create an instance of your class.
Also, MyClass has a reference to a MyClass object. In the constructor of MyClass, it initializes that reference by calling it's own constructor. That's an endless loop.
Do the following. Your way of initialization is wrong.
public class MyClass{
String[] arr;
MyClass my;
public MyClass(){
}
public class MyInner {
public void MyMethod() {
// I need to access 'my.arr' from here how can i do it.
}
}
public static void main(String[] args) {
String[] n={"ddd","f"};
MyClass my=new MyClass();
String[] b = new String[2];
System.arraycopy( n, 0, b, 0, n.length );
}
}
In case of more than 2 strings, simply do String[] b = new String[n.length];

Java: Anonymous inner class using a local variable

How can I get the value of userId passed to this method in my anonymous inner subclass here?
public void doStuff(String userID) {
doOtherStuff(userID, new SuccessDelegate() {
#Override
public void onSuccess() {
Log.e(TAG, "Called delegate!!!! "+ userID);
}
});
}
I get this error:
Cannot refer to a non-final variable userID inside an inner class defined in a different method
I'm pretty sure I can't assign it as final since it's a variable with an unknown value. I had heard that this syntax does preserve scope in some way, so I think there must be a syntax trick I don't quite know yet.
As everyone else here has said, local variables have to be final to be accessed by an inner class.
Here is (basically) why that is... if you write the following code (long answer, but, at the bottom, you can get the short version :-):
class Main
{
private static interface Foo
{
void bar();
}
public static void main(String[] args)
{
final int x;
Foo foo;
x = 42;
foo = new Foo()
{
public void bar()
{
System.out.println(x);
}
};
foo.bar();
}
}
the compiler translates it roughly like this:
class Main
{
private static interface Foo
{
void bar();
}
public static void main(String[] args)
{
final int x;
Foo foo;
x = 42;
class $1
implements Foo
{
public void bar()
{
System.out.println(x);
}
}
foo = new $1();
foo.bar();
}
}
and then this:
class Main
{
private static interface Foo
{
void bar();
}
public static void main(String[] args)
{
final int x;
Foo foo;
x = 42;
foo = new $1(x);
foo.bar();
}
private static class $1
implements Foo
{
private final int x;
$1(int val)
{
x = val;
}
public void bar()
{
System.out.println(x);
}
}
}
and finally to this:
class Main
{
public static void main(String[] args)
{
final int x;
Main$Foo foo;
x = 42;
foo = new Main$1(x);
foo.bar();
}
}
interface Main$Foo
{
void bar();
}
class Main$1
implements Main$Foo
{
private final int x;
Main$1(int val)
{
x = val;
}
public void bar()
{
System.out.println(x);
}
}
The important one is where it adds the constructor to $1. Imagine if you could do this:
class Main
{
private static interface Foo
{
void bar();
}
public static void main(String[] args)
{
int x;
Foo foo;
x = 42;
foo = new Foo()
{
public void bar()
{
System.out.println(x);
}
};
x = 1;
foo.bar();
}
}
You would expect that foo.bar() would print out 1 but it would actually print out 42. By requiring local variables to be final this confusing situation cannot arise.
Sure you can assign it as final - just put that keyword in the declaration of the parameter:
public void doStuff(final String userID) {
...
I'm not sure what you meant about it being a variable with an unknown value; all that final means is that once a value is assigned to the variable, it cannot be re-assigned. Since you're not changing the value of the userID within your method, there's no problem making it final in this case.
In Java 8, this has changed a little bit. You can now access variables that are effectively final. Relevant snippet and example from the Oracle documentation (emphasis mine):
However, starting in Java SE 8, a local class can access local
variables and parameters of the enclosing block that are final or
effectively final.
Effectively final: A non-final variable or parameter whose value is never changed after it is initialized is effectively final.
For example, suppose that the variable numberLength is not declared final, and you
add the highlighted assignment statement in the PhoneNumber
constructor:
PhoneNumber(String phoneNumber) {
numberLength = 7; // From Kobit: this would be the highlighted line
String currentNumber = phoneNumber.replaceAll(
regularExpression, "");
if (currentNumber.length() == numberLength)
formattedPhoneNumber = currentNumber;
else
formattedPhoneNumber = null;
}
Because of this assignment statement, the variable numberLength is not
effectively final anymore. As a result, the Java compiler generates an
error message similar to "local variables referenced from an inner
class must be final or effectively final" where the inner class
PhoneNumber tries to access the numberLength variable:
if (currentNumber.length() == numberLength)
Starting in Java SE 8, if you declare the local class in a method, it
can access the method's parameters. For example, you can define the
following method in the PhoneNumber local class:
public void printOriginalNumbers() {
System.out.println("Original numbers are " + phoneNumber1 +
" and " + phoneNumber2);
}
The method printOriginalNumbers accesses the parameters
phoneNumber1 and phoneNumber2 of the method validatePhoneNumber
What's the problem with making it final as in
public void doStuff (final String userID)
declare the method
public void doStuff(final String userID)
The value needs to be final so that the compiler can be sure it doesn't change. This means the compiler can bind the value to the inner class at any time, without worrying about updates.
The value isn't changing in your code so this is a safe change.

Categories

Resources