At the moment the class is instantiating Teste
in the static field need to create the implementation of the abstract method and this is what it does correctly, after all abstract classes cannot be instantiated directly. So what happens when you create this instance?
There is a class heritage Teste
for a temporary (anonymous) class to allow the extension of the class and method implementation that was not implemented. It’s kind of weird, but that’s how it works, in practice it’s not instantiating well Teste
and yes a class derived from it, although in the code this is not visible.
It’s also weird because it’s instantiated within the class itself, but static members are like that, they’re there almost by chance, it could be in other places, they don’t belong to the object, they don’t see the members of the object directly. Think of him as somewhere else because it’s the same.
If you want to know more read Static reference giving error while accessing and What is the use of a static or final variable in java?.
So the moment you call teste1()
everything works because you have access to a public method from anywhere in the application, as long as an object of this type is instantiated it can be called, so it is with all public members.
It’s okay to call teste2()
which is protected. This method cannot be called from anywhere, it can only be called from a class that is derived from the base class, i.e., it has to be derived from Teste
. And in fact this is what happens as I explained in the second paragraph, you have there an invisible class derived from Teste
.
Already teste3()
cannot be called because it is private, i.e., it can only be called within an object of the class Teste
. You can’t even call a derivative of it that is the case you created there. And gives the error.
You may be thinking, "but you’re inside Teste
". It’s inside the class, not the object, static members are not part of the object, by chance it’s all together, but it’s like something separate, so it doesn’t work.
Read What is the difference between a class and an object?. Also What is the difference between class instance variables, automatic (local) and static duration?.
If you believe it should work you should justify why it should. If you can’t justify it then you can’t. Nothing should work without justification.
The example is good and helps in learning many people, pity that the site has no longer attracted more people who want to know it, but the question is a boost.
The error displayed is confusing because "this" is implied. If you modify all test calls to contain "this." , the actual error appears: "The method teste3() from the type Test is not Visible", which is much less confusing.
– dvlcube
So, for me it was not very clear why is giving the error that gives. I should give that the method is not visible.
– Piovezan
From what I understand, it’s not visible at all. Because an "invisible class" is created somewhere, and because it is outside the Test class, it cannot access the private method.
– user201641
@Piovezan Hunch: this seems to be a corner case strange, I don’t know. Anyway, if the method is
private static void teste3()
, then the code compiles (that’s because to bestatic
the visibility rules in the subclasses are no longer valid), so in the above code the compiler should consider that you tried to call a method that should be static but is not, since it is in a static context.– hkotsubo
On the other hand, if you try to create a subclass (instead of a static field), then you get the error of "cannot find Symbol" as expected: https://repl.it/repls/AlertCoralMethods#Test.java - then my guess is that the compiler first tries to check the static context, and then check the visibility rules. Unless, of course, you explicitly called for
this.teste3()
, as already said above, because there it makes clear that does not want to call the static method, and there gives the error that the method is not visible.– hkotsubo
@hkotsubo Ah, now I understand what it means to "contain
this.
on calls fromteste()
". I had not understood, I thought it was to add in the parameter. And thanks for the explanation :)– Piovezan
@Piovezan If you want, you can look in the source code of the compiler to be sure: http://openjdk.java.net/groups/compiler/ :-) (no, I didn’t look)
– hkotsubo
@hkotsubo Thanks for the tip, but I won’t look no. Good to know it exists, but I’d rather not commit these corner cases. If it is for the daughter class to see, it should not be private. It is better not to abuse of inheritance, as you well know.
– Piovezan