Java. Can i delete instance of class from method of this class? - java

public class Foo{
public Foo(){}
public void Method()
{
this = null; //doesn't work
}
}
I know that in C# i can't do this, but may be can in Java?

nope , you can not do.
you will get below error.
The left-hand side of an assignment must be a variable

Can i delete instance of class from method of this class?
There is no instance of the class yet unless you've created it.
Foo foo=new Foo();
You can dereference foo by
foo=null;
Now the foo object which the foo reference points to on the heap will be collected by garbage collector
public class Foo{
public static void main(String[] args)
{
Foo foo=new Foo();
System.out.println(foo);
foo=null;
System.out.println(foo);
}
}
Output
Temp#1a8c4e7
null

Can i delete instance of class from method of this class?
No. Because it doesn't make sense right. You didn't create any object so far and you are trying to dereference it..??
In Java, Memory management is handled by JVM and all the objects are destructed by JVM when they are no more referenced.
So you can not guarantee an instance to be deleted at specific time.
public class Foo {
public Foo() {
}
public void Method() {
// some code
}
}
public class Test {
public static void main(String[] args){
Foo foo = new Foo(); // Constructor-Instance created and referenced
foo = null; // reference variable foo is made null.
}
}
Once foo is made null, the instance for Foo is available for GC.

Related

Class initialization trouble: static variables are null when accessed [duplicate]

I'm running into a problem when I compile my code. When I compile my code foo2.var returns null in class foo and I can't seem to figure out why. Is there something wrong in how I'm doing the static initialization in the foo2 class to cause foo2.var to be null in the foo class?
Any help is appreciated.
public class foo extends bar {
public final static String blah = foo2.var;
...
}
public abstract class bar {
...
}
public class foo2 extends bar {
public final static String var;
static {
var = "newstring";
}
...
}
Null pointer error on the foo2.var line in this example.
Accessing a static field (whose value is not a compile-time-constant expression) will trigger initialization of the class declaring that field, during which which the static initializers are executed. However, initialization is only guaranteed to have completed by the time the field is read if there is no cyclic dependency among initializers.
For instance, if you run the program
class Bar {
static final long bar;
static {
System.out.println("Assigning bar");
bar = Foo.foo;
}
}
class Foo extends Bar {
static final long foo;
static {
System.out.println("Assigning foo");
foo = 1;
}
}
public class Test {
public static void main(String[] args) {
new Foo();
System.out.println(Bar.bar);
}
}
you get the following output:
Assigning bar
Assigning foo
0
1
because to create a new instance of Foo, Foo.class is initialized, which first initializes its super class Bar.class, which reads the field of Foo.class, but Foo.class is already being initialized. The Java Language Specification mandates in section 12.4.2, step 3, that such a recursive initialization completes immediately, i.e. the caller will see the class in a partially initialized state. That is, Foo.foo is unassigned at the time it is read, and therefore still contains the default value of 0. That value is assigned to Bar.bar, completing initialization of Bar.class. Then, initialization of Foo.class is resumed by running the initializer, which sets Foo.foo to 1.
Practically speaking, you might wish to review the dependencies of your classes and structure your program such that there are no cyclic dependencies among initializers.
You have not specified a type for var try public final static String VAR;
and then why not just
public class foo2 extends bar {
public final static String var = "newstring";
var doesn't have a type. Also constants in Java are uppercase by convention. Make it:
public class Foo2 {
public final static String VAR;
static {
VAR = "newstring";
}
...
}
You are missing a type for var, change that line to the following:
public final static String VAR;
Specify var type.
Also, by coding convention class names should be written in CamelCase and constants, UNDERSCORED_CAPS
public class Foo2 {
public final static VAR = "newstring"; // why not?
...
}
Also, you may shadow foo2 class by some variable. Check your imports. Because class static field reference cannot produce NPE!

Does editing an object within a function mean I need to return it back to update the value

If I edit the data of an object in a function do I need to return the object back to update it in java.
Say I have something like this:
public void foo1() {
Foo foo = new Foo();
someFunction(foo);
// Is the state of foo changed here or not?
}
public void someFunction(Foo foo) {
foo.doSomething();
}
I know objects are passed by reference in java. Will this mean the object is updated/changed at the end of the foo1() function or not?
Does foo change? It's possible but it depends on what the method does.
Here's an example where foo does not change:
public class NoChange {
public static void main(String[] args) {
Foo foo = new Foo();
foo.noChange();
}
}
class Foo {
private int n = 0;
public void noChange() {
System.out.println(n);
}
}
If you run this code, the call to foo.noChange() will print out "0", and nothing in foo will change.
Here's a slight modification of that example which introduces a doChange() method on class Foo. The new method does change something in an instance of Foo – specifically, it takes the value of n and increments it by one.
public class YesChange {
public static void main(String[] args) {
Foo foo = new Foo();
foo.doChange(); // increment n by one
foo.noChange(); // print out n
}
}
class Foo {
private int n = 0;
public void noChange() {
System.out.println(n);
}
public void doChange() {
n++;
}
}
When you run that second example code – which first calls doChange(), then calls noChange() to print out current "n" – the output is "1".
So, the behavior depends on whether the method changes state (for example, by changing setting a value such as incrementing a number) or has side effects (the method might call some other method which in turn does change state). If the method does none of these things, it would be a "pure function".

Is there any annotation to warn that subclasses shouldn't hide a static method in Java

I have a class which contains a public static method in Java. Is there any annotation in java to warn the subclasses not to use same method signature(and thereby hide the superclass method). Any other workarounds would also be fine.
Just make the superclass method final:
class Foo {
public static final void go() {}
}
class Bar extends Foo {
public static void go() {}; // Error
}
Ideone Example
you dont need such annotations because what you a trying to do in not going to compile...
in java you just can not override static method
as #thomas suggested(+1 dafuer), you can play with the visibility of the static method
example:
public class Calculator {
static int add(int a, int b) {
System.out.println("a+b= " + (a + b));
return a + b;
}
public static void main(String[] args) {
}
}
and then
public class ScientificCalculator extends Calculator {
public int add(int a, int b) {
System.out.println("11111");
return a + b;
}
}
I don't know of any such annotation to flag the declaration of the method. You could, however, approach this from the opposite direction. Instead of focusing on the method declaration, you could look at uses of it. The -Xlint:all will warn if any uses could be a problem. A static method with an identical signature to a static method in its superclass will only cause problems when that method is referenced from an instance instead of statically. Consider this example:
public class Foo {
public static String getFoo(){
return "foo";
}
}
public class Bar extends Foo {
public static void main(String[] args){
Bar bar = new Bar();
String s = bar.getFoo(); // Actually calls Foo.getFoo()
System.out.println(s); // Prints "foo"
}
}
In the code above, we reference the static getFoo() method from Foo through an instance of Bar. The bar.getFoo() line actually calls the static method from Foo. Now suppose we add a static method with an identical signature to Bar:
public class Bar extends Foo {
public static String getFoo(){
return "bar";
}
public static void main(String[] args){
Bar bar = new Bar();
String s = bar.getFoo(); // Actually calls Bar.getFoo()
System.out.println(s); // Prints "bar"
}
}
This hides the Foo.getFoo() method from Bar and now the Bar.getFoo() method is invoked instead. In a real context, this would almost certainly break Bar. If you compile with the -Xlint:all option, then you'd get this message:
warning: [static] static method should be qualified by type name, Foo, instead of by an expression
You'd notice this when you compile the first version of Bar and you could fix it to String s = Foo.getFoo() right away. Later when getFoo is also added to Bar, the original code will still work because it explicitly references the method in Foo. If you always explicitly call static methods by referencing the class in which they are declared, then the only problem with having an identical method in a subclass is that it's not exactly a best practice. Maybe there is a way to flag the declaration, too, but I'd focus on making sure that the static method is used properly.

Is passing object to constructor pass by reference [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 9 years ago.
Suppose I have a class and constructor called TestClass.
public class TestClass {
Foo foo;
public TestClass(Foo foo) {
this.foo = foo;
}
}
Here, the constructor accepts an object which is an instance of class Foo. Suppose my static void main(String[] args) does the following, completely separate from any TestClass;
(1) Instantiate foo
(2) Pass instance foo to TestClass constructor
(3) Change the internal state of foo
After step (3), will the foo within my instance of TestClass also have its state changed?
It is not passed by reference. Rather, it is passed by value of the reference, which is a subtle but important distinction.
After you mutate foo in the rest of your main() method, the foo field will also exhibit these mutations, as you state, since both variables point to the same instance. However, if you reassign foo to something new, the foo field will not be changed. This would not be true if foo were truly passed by reference. In short, everything is passed by value in Java; it just so happens that objects are dealt with by reference, and so the values of these references are passed.
I'll try to illustrate this with an example. Consider the following class:
class A {
public int n;
public A(int n) {
this.n = n;
}
}
and the following method:
public static void mutate(A a) {
a.n = 42;
}
Now we can have something like this:
A a = new A(0);
A.mutate(a);
System.out.println(a.n);
42
We can see that the state of a was changed in mutate(). Now let's modify the static method:
public static void mutate(A a) {
a = new A(42);
}
and try again:
A a = new A(0);
A.mutate(a);
System.out.println(a.n);
0
As you can see, the state of a is unchanged. If the reference had been passed to the function, we would expect the effect of the reassignment to be evident beyond the scope of the method. Nevertheless, some reference was in fact passed, since mutating the argument caused changes outside of the method as well.
Yes, because you are assigning same object to another reference of Foo class, i.e. object is same, but being referred by two reference.
After step (3), will the foo within my instance of TestClass also have
its state changed?
Yes.
You might like to take a read through this
Updated...
Now, assuming you pass the constructor a primitive value...
public class TestClass {
int foo;
public TestClass(int foo) {
this.foo = foo;
}
public String toString() {
return "TestClass: " + foo;
}
}
public static void main(String args[]) {
int myFoo = 1;
TestClass test = new TestClass(myFoo);
myFoo += 2;
System.out.println("myFoo = " + myFoo);
System.out.println("yourFoo = " + test);
}
This will output...
myFoo = 3
yourFoo = 1
Which demonstrates the fact that changing the value of a primitive does not change the value maintained by the constructor/method.
Equally, if you change the object reference after you pass it
public class TestClass {
Foo foo;
public TestClass(Foo foo) {
this.foo = foo;
}
public Foo getFoo() {
return foo;
}
}
public static void main(String args[]) {
Foo myFoo = new Foo();
TestClass test = new TestClass(myFoo);
myFoo = new Foo();
System.out.println("myFoo == yourFoo = " + myFoo.equals(test.getFoo()));
}
Will output
myFoo == yourFoo = false
As the object references are not the same.

Global variables and constructor(Java)

When are variables at the top of the class initialized in comparison to the constructor?
Sorry, this is what I meant:
public class aClass {
private int num;
public aClass {...}
Default values (null for object fields, 0 etc. for primitive fields`) are technically never explicitly assigned as far as the emitted bytecode is concerned. (This is done "internally" during object instantiation, before any initializer/constructor code runs.)
Explicit initializer code for instance fields is "copied" at the start of every constructor, after a superclass constructor call (if there is any) in the class by the compiler. The code sample:
class Foo {
int bar = 123;
public Foo() {
// ...
}
public Foo(int bar) {
this.bar = bar;
// ...
}
}
is compiled into bytecode equivalent to:
class Foo {
int bar;
public Foo() {
this.bar = 123;
// ...
}
public Foo(int bar) {
this.bar = 123;
this.bar = bar;
// ...
}
}
Same goes for initializer blocks. This means these variables get initialised before any normal constructor code executes.
Members defined with values are initialized in the constructor, just like any other members. But it's not exactly the constructor you wrote; Java changes each constructor behind the scenes by inserting member initializers and initializer blocks in the beginning of it. You could view it as the members getting initialized just before the constructor, if you want to view it temporally.
Effectively, you can consider them initialized before your constructor gets called. So if you have:
class Dog {
private String voice = "woof";
public Dog() {
System.out.println(voice);
}
}
You'll get "woof" printed to the console successfully, rather than null.

Categories