Following the this code of block of the image what is the expecting result
on the rabbit class I'm confused if the way the Hole class is instantiated is valid I'm assuming it is so the output will be
Here is the image with the code:
"dig'
"dig"
9
The expected output would be
dig dig 9
The first call:
Hole.dig()
is a standard static method call which I assume doesn't surprise you.
The second call:
new Hole().dig()
is pretty bad code. (fine for when you are learning but not so great in the workplace). Your editor likely is warning you about this. This is calling the static dig() method but based on the declared/implied type of new Hole();
It is bad code because it will give you the idea that the instance has something to say about which method is being called.
for instance:
public static void main(String[] args) {
new A().printMe();
new C().printMe();
A whichOne = new C();
whichOne.printMe();
}
public static class A {
public static void printMe() {
System.out.println("A");
}
}
public static class C extends A {
public static void printMe() {
System.out.println("C");
}
}
this will print A , not C as you might expect. You are creating a C object but after you put it into an A variable, the static method will use the class of the containing variable to decide which method to call.
new C().printMe();
A whichOne = new C();
whichOne.printMe();
// gives C , A
This is confusing and generally frowned upon.
Lastly the static import:
import static hole.Hole.*; // import all static methods and variables from hole.Hole into here.
it pulls in Depth and any other methods (including dig, so just calling this would work as well:
dig();
When the Hole class is loaded it first sets Depth to 3. But even before the constructor is called the static block sets Depth to 9. So that is why Depth would contain 9.
Related
Seems like a very basic query but I was pondering how the static method main() below is able to execute a non static method(the constructor obviously) from it using the new keyword. Though I understand that new brings onto the table a few other things as well but how should I convince myself that this isn't an exception to the rule that static and non static methods can't using non static and static context respectively?
Below is the sample code:
public class ConstructorTest {
ConstructorTest(String str)
{
System.out.println("Constructor Printing "+str);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ConstructorTest cnst=new ConstructorTest("here");
}
}
The above code actually prints --> Constructor Printing here
or in other words executing the body of a Non static method from a Static method?
Any plausible explanations are welcome.
The Java Tutorial states that
[...] Constructors are not members.
Therefore, there is no problem in calling them, since they are not bound to instances of your class. This would not make sense - hence, you cannot do the following:
Thing thing = new Thing();
Thing anotherThing = thing.Thing();
A constructor is not a method, so you cannot apply "method logic" to them.
In case you want to know more, the whole instantiation process is very well documented in the JLS. See 12.5. Creation of New Class Instances.
Actually constructor is compiled into the static method, this is how JVM internally creates instances of classes.
You are executing non-static code, but you are not doing it in a static context.
for instance:
public class C1{
private int x;
public String do(){ System.out.println("x = " + x);}
public static void main(String[] args){
do();
}
}
This can not work, since do is an instance method, which might run code that is specific to the instance. So, how would the VM know which instance to use, or what value x should have?
Now, to first use a constructor, which is possible from any context:
public class C1{
private int x;
public String do(){ System.out.println("x = " + x);}
public static void main(String[] args){
C1 t = new C1();
t.do();
}
}
Here, even though you are calling the method from within a static method, you are using it through an instance, so not in a static context.
ConstructorTest is not a method.
its an constructor,and you can use the constructor for initialize class property.
you can also initialize the static variable from the constructor like that :-
public class XYZ
{
static int i=0;
public XYZ() {
i=1;//not an compile time error
}
public static void doSome(){}
public static void main(String[] args) {
}
}
On a formal language level you should read the line
ConstructorTest cnst = new ConstructorTest("here")
as a class instance creation expression. As a matter of fact, this is not a call to a constructor or any other method.
The instance creation does many steps, like allocating memory for the new object, initializing the fields, calling constructors and initializer blocks. See JLS §12.5 for a detailed step-by-step description. Thus being said, the constructor invocation is only a part of the instance creation.
Additionally, you might see constructors as being static parts of the class. In fact, constructor declaration are not members (see JLS §8.8) and thus they are not overridable (as static methods also). Beware: This is only half true. When being inside the constructor you already have the instance created, and you are able to call other instance methods and/or access instance fields.
This question already has answers here:
Cannot make a static reference to the non-static method
(8 answers)
Closed 8 years ago.
I am working on a school project, building a Chess-game. I have my board which creates the arrays and fill the board with pieces.
Now, I want to instantiate a new board in a game class and use the console to input player moves. To make this as simple as possible, my trouble is inputting non-static variables.
For instance:
public class Test extends ConsoleProgram{
public static double a1;
public static void main(String[] args) {
a1 = readLine("Insert value of a1");
System.out.println(a1);
}
}
more info on readLine() here
As you probably see, this won't work as java is complaining cannot make static reference to the non-static method readLine()
How do I work around this? Maybe there is something really basic I just don't understand..
As always, thank you very much for your quick and insightful answers!
If you don't want to make your readLine method static, do a call on an instance:
public static void main(String[] args) {
Test me = new Test();
a1 = me.readLine("Insert value of a1");
System.out.println(a1);
}
either define readline as static or
make an object of class and then call the method, new Test().readline();
Make readLine()` as static.Then you can access
If you make method as static then you can use that in main() method
otherwise create an object for Test class then use it
The simplest work around I've found is simply instantiate the object in the main method, and call the relevant methods from the constructor.
public static void main(String[] args)
{
new ClassThing();
}
public ClassThing()
{
// Make your method calls here.
}
This means you can access instance methods, and you don't need to call everything from a static context.
Create Test instance in main and call it's instance method.
public class Test extends ConsoleProgram {
public double a1;
public void run() {
a1 = readLine("Insert value of a1");
System.out.println(a1);
}
public static void main(String[] args) {
Test main = new Test();
main.run();
}
}
You should instantiate an object of the class that has the method readLine().
If that class' name is i.e. Reader you should do something like:
Reader r= new Reader();
a1 = r.readLine("Insert...");`
I have a simple Java theory question. If I write a class that contains a main() method along with some other methods, and within that main method invoke an instance of the class (say new Class()), I'm a bit confused why a recursion doesn't occur. Let's say I'm writing a graphing program, where the other methods in the class create a window and plot data; in the main method I call an instance of the class itself, and yet only one window appears. That's great, and it's what I wanted, but intuition suggests that if I create an instance of a class from within itself, some sort of recursion should occur. What prevents this? Here is an example (in my mind, I'm wondering what prevents unwanted recursion):
public class example{
method1(){create Jpane}
method2(){paint Jpane}
method 3(){do some computations}
public static void main(String[] args){
new example(); // or create Jblah(new example());
}
}
I think you're confusing the main method - which is just the entry point of the program - with a constructor.
For example, if you wrote:
public class Example {
public Example() {
new Example(); // Recursive call
}
public static void main(String[] args) {
// Will call the constructor, which will call itself... but main
// won't get called again.
new Example();
}
}
Then that would go bang.
The main method does not get executed automatically when you instance a class. It simply can be used as an entry point to an application - and then will be executed once.
Recursion isn't a bad thing. I suspect you are asking why there isn't an infinite recursion.
The big concept you are missing is that when you call new Example() you are allocating memory and then invoking just one method (the constructor). The main() is only invoked at the start of the whole program unless you explicitly call it.
--- edited to add
public class MyMainClass {
public static void main(String arg[]) {
Calculator c = new Calculator();
int x = c.factorial(5);
}
}
class Calculator {
Calculator() { }
public int factorial(int x) {
if (x > 1) return x * factorial(x - 1);
else return 1; // WARNING: wrong answer for negative input
}
}
Since factorial doesn't use any instance variable, it could have been declared static and called as Calculator.factoral(5); without even using new, but I din't do that since showing off new was the whole point of the example.
just because you have a main method in the class doesn' mean that it will be called every time you create the class.
Java looks for main as an entry point for the program, and calls it upon startup. Any objects you instantiate from their do not call main, since as far as java is concerned, it has done its job of making the entry point to the program.
When a class extends another, it inherits all methods and variables of the superclass. Both methods and variables can be used differently in the subclass, if you define it differently in the subclass with the same signature.
Now Oracle distincts between overwriting and hiding (http://docs.oracle.com/javase/tutorial/java/IandI/override.html).
It says that an instance method overwrites its superclass's method, while a class method hides it.
"The distinction between hiding and overriding has important implications. The version of the overridden method that gets invoked is the one in the subclass. The version of the hidden method that gets invoked depends on whether it is invoked from the superclass or the subclass."
Lets assume I have 2 classes Yes and Maybe. Yes extends Maybe.
Maybe has String a.
class Maybe {
String a;
public static void printOut() {
System.out.println("Maybe");
}
public void printAndSet() {
a = "Maybe";
System.out.println(a);
}
}
class Yes extends Maybe {
public static void printOut() {
System.out.println("Yes");
}
pubilc void printAndSet() {
a = "Yes";
}
}
class Print{
public static void mail(String[] args) {
Maybe m = new Maybe();
Yes y = new Yes();
Maybe.printOut();
Yes.printOut();
m.printAndSet();
y.printAndSet();
}
And I say: It will print out
maybe
yes
maybe
yes
But after I read the Oracle article I thought it would have to print out:
yes
yes
maybe
yes
Because the instance method overwrites its superclass method.
I'm quite sure I am right with the output, but I'm sure aswell, that Oracle knows
better so I'm thinking I just didn't understand the article.
It can't be true that when I call an instance method from an object of a superclass, that it uses the overwritten method.
So I do not understand why to distinguish overwriting and hiding!
Can someone help out?
Edit; Inserted code instead of describing the classes!
Static methods can't be overridden at all. They're not called polymorphically, since they don't act on an instance of the class, but on the class itself.
If you call Maybe.printOut(), it will call the static printOut() method defined in Maybe. The fact that there is also a method printOut() defined in Yes is irrelevant: those two methods have nothing in common, except their name.
Note that you could confirm or infirm your doubts by simply writing a program and executing it.
The problem with hiding methods only occurs when you start calling static methods on an instance of an object. This is very bad practice, and should never be done. If you don't respect this rule, and have the following:
Maybe m = new Maybe();
Maybe y = new Yes();
m.printOut(); // DON'T DO THAT: it should be Maybe.printOut();
y.printOut(); // DON'T DO THAT: it should be Maybe.printOut() or Yes.printOut();
the result will be maybe maybe, because in the case of static methods, what counts is not the concrete type of the objects (Maybe and Yes), but their declared type (Maybe and Maybe).
public class Parent {
public String test(){
return "p";
}
public static String testStatic(){
return "sp";
}
}
public class Child extends Parent {
public String test(){
return "c";
}
public static String testStatic(){
return "sc";
}
}
public class Demo{
public static void main(String[] args) {
Parent p =new Parent();
Child c = new Child();
Parent pc = new Child();
System.out.println(p.test());
System.out.println(c.test());
System.out.println(pc.test());
//Although this is not the correct way of calling static methods
System.out.println(p.testStatic());
System.out.println(c.testStatic());
System.out.println(pc.testStatic());
}
}
OUTPUT will be: - (static method vs instance method)
p
c
c
sp
sc
sp
Take the following example, based on your example:
public class SO11720216 {
static class Maybe {
public static void hidden() { System.out.println("static maybe"); }
public void overwritten() { System.out.println("instance maybe"); }
public void inherited() { hidden(); }
public void called() { overwritten(); inherited(); }
}
static class Yes extends Maybe {
public static void hidden() { System.out.println("static yes"); }
public void overwritten() { System.out.println("instance yes"); }
}
public static void main(String[] args) {
Maybe m = new Maybe();
Yes y = new Yes();
m.called(); /* prints:
instance maybe
static maybe
*/
y.called(); /* prints:
instance yes
static maybe
*/
Yes.hidden(); /* prints: static yes */
y.hidden(); /* bad style! prints: static yes */
}
}
The call to overwritten will be overwritten by each derived class. So every method will use the implementation belonging to the current object. On the other hand, the call to hidden will always use the implementation of the defining class. Hence Maybe.called will always call Maybe.hidden, and never Yes.hidden. To call Yes.hidden, you'll have to do so from within a method in Yes, or using a qualified name.
To phrase this differently:
To overwrite a method means that whenever the method is called on an object of the derived class, the new implementation will be called.
To hide a method means that an unqualified call to that name (like the hidden() call in the inherited() method of my above example) in the scope of this class (i.e. in the body of any of its methods, or when qualified with the name of this class) will now call a completely different function, requiring a qualification to access the static method of the same name from the parent class.
Perhaps your confusion comes from the fact that you assumed overwriting to affect all calls to the method, even for objects of the base class.
Suppose the classes has code like this:
class C {
public static void show() {
}
}
class CTest {
public static void main (String[] args) {
C.show();
}
}
Then will it be perfectly legal to conclude that while referring to class C to access the static method show() here, behind the scene Java is actually calling the show() method through Java reflection ?
I.e. is it actually doing something like this
Class test = Class.forName(C);
test.show();
to call static methods?
If not, then how is it actually calling the static methods without creating objects?
If the above explanation is true, then how we'll justify the statement that "static members are only associated with classes, not objects" when we're actually invoking the method through a java.lang.Class object?
The JVM doesn't need to do anything like Class.forName() when calling a static method, because when the class that is calling the method is initialized (or when the method runs the first time, depending on where the static method call is), those other classes are looked up and a reference to the static method code is installed into the pool of data associated with that calling class. But at some point during that initialization, yes, the equivalent of Class.forName() is performed to find the other class.
This is a specious semantic argument. You could just as easily say that this reinforces the standard line that a static method is associated with the class rather than any instance of the class.
The JVM divides the memory it can use into different parts: one part where classes are stored, and one for the objects. (I think there might have been third part, but I am not quite sure about that right now).
Anyways, when an object is created, java looks up the corresponding class (like a blueprint) and creates a copy of it -> voila, we have an object. When a static method is called, the method of the class in the first part of the memory is executed, and not that of an object in the second part. (so there is no need to instantiate an object).
Besides, reflection needs a lot of resources, so using it to call static methods would considerably impact performance.
For extra info:
The called class will get loaded when it's first referenced by calling code.
i.e. The JVM only resolves and loads the class at the specific line of code that it first needs it.
You can verify this by using the JVM arg "-verbose:class" and stepping through with a debugger.
It will call ClassLoader.loadClass(String name) to load the class.
You can put a println statement into the ctor, to verify, whether it is called or not:
class C {
public static void show () {
System.out.println ("static: C.show ();");
}
public C () {
System.out.println ("C.ctor ();");
}
public void view () {
System.out.println ("c.view ();");
}
}
public class CTest
{
public static void main (String args[])
{
System.out.println ("static: ");
C.show ();
System.out.println ("object: ");
C c = new C ();
c.view ();
c.show (); // bad style, should be avoided
}
}