This question already has answers here:
What is the difference between public, protected, package-private and private in Java?
(30 answers)
Closed 7 years ago.
I have a class in a different package where i declared a protected member. as shown
package Pack1;
public class Box {
public Box()
{
System.out.println("Box Class Contructor");
}
protected int x = 1;
protected void Hello1()
{
System.out.println("Hello!!");
}
}
Now i am extending this class to another package to call its protected member as shown:
public class Main extends Pack1.Box {
public Main()
{
System.out.println("main constructor");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Main main = new Main();
main.Hello1(); // not giving me any error
Pack1.Box b = new Pack1.Box();
b.Hello1();//Giving me an error
}
}
I am not sure why b.Hello1() is giving me an error inspite of being inherited. But if i declare the Hello1() as protected static void it is not giving me an error.
For accessing protected method() , variables from class located in other package we need Inheritance.
As i can see you have already used inheritance and inherited the class box of package pack1 correctly.
Now all except default and private members of that class aren't visible. What is visible to you the members those are declared as protected and public.
Now you can assume those methods are available in ur class.
So, instead of calling method by object reference of that class will give you an error , while it won't give you any error if you call that method directly but in the constructor of a class ie Main() class in your case.
Why because,
There are two main restrictions for the static method.
They are:
1)The static method can not use non static data member or call non-static method directly.
2)this and super cannot be used in static context.
Try to call Hello1() method from class constructor. It will work.
The protected method Hello1() is defined in the Pack1, so you can't invoke it from another package - only from subclasses like this:
Main main = new Main();
main.Hello1();
protected allows access from subclasses and from other classes in the same package.
When you use your method static.
You might wonder "what's the reason for a static protected method, considering that it's impossible to call it from anywhere except from an instance of that class?". Usually there isn't much reason to declare a private or protected method as static. Static methods are usually public.
Related
This question already has answers here:
Why java.lang.Object can not be cloned?
(10 answers)
Closed 4 months ago.
Object's clone method is protected, therefore it can be accessed in sub classes (class A), so why am I getting 'clone() has protected access in java.lang.Object' compiler error? I thought, that all Java classes are sub classes of Object. Thanks in advance.
The code below raises the compiler error:
public class A {
public static void main(String[] args) {
Object o = new Object();
o.clone();//error
}
}
But this one compiles perfectly, don't they have the same semantics tho?
public class A {
protected void foo() {
}
}
public class B extends A {
public static void main(String[] args) {
A a = new A();
a.foo();
}
}
No, they don't.
protected means 2 things:
It's like package, _and that explains why your second snippet can call foo(). It's not about the fact that B extends A, it's that A is in the same package as B.
Subclasses can invoke it.. on themselves only. Trivially (but this doesn't work if its final), you can simply override it, implement it as return super.clone(); and now you can call it just fine.
protected members can be accessed anywhere in the same package and outside package only in its child class and using the child class reference variable only, not on the reference variable of the parent class. We cant access protected members using the parent class reference.
Consider the following code snippets:
package vehicle;
public abstract class AbstractVehicle {
protected int speedFactor() {
return 5;
}
}
package car;
import vehicle.AbstractVehicle;
public class SedanCar extends AbstractVehicle {
public static void main(String[] args) {
SedanCar sedan = new SedanCar();
sedan
.speedFactor();
AbstractVehicle vehicle = new SedanCar();
// vehicle //WON'T compile
// .speedFactor();
}
}
SedanCar is a subclass of AbstractVehicle which contains a protected method speedFactor. I am able to call the method speedFactor if it is referenced by the same class. When the super class is used for reference the method speedFactor is not accessible.
What is reason for hiding the method?
Your SedanCar class is in a different package than the AbstractVehicle class. protected methods can only be accessed from the same package or from subclasses.
In case of SedanCar:
SedanCar sedan = new SedanCar();
sedan.speedFactor();
You are calling a protected method from the same package: OK. SedanCar is in package car and main() method is in a class which is in package car (actually the same class).
In case of AbstractVehicle:
AbstractVehicle vehicle = new SedanCar();
vehicle.speedFactor();
You try to call a protected method but from another package: NOT OK. The main() method from which you try to call it is in package car while AbstractVehicle is in package vehicle.
Basically understand this:
You have a variable of type AbstractVehicle which is declared in another package (vehicle). It may or may not hold a dynamic type of SedanCar. In your case it does, but it could also hold an instance of any other subclass defined in another package, e.g. in sportcar. And since you are in package car (the main() method), you are not allowed to invoke vehicle.speedFactor() (which is the protected AbstractVehicle.speedFactor()).
Because protected is visible to the class itself (like private) and its subclass instances. It is not public.
For example,
package vehicles;
public abstract class AbstractVehicle {
protected int speedFactor() {
return 5;
}
public int getSpeed() {
return 10*speedFactor(); //accessing speedFactor() "privately"
}
}
package vehicles.cars;
public class SedanCar extends AbstractVehicle {
#Override
protected int speedFactor() { //overriding protected method (just to show that you can do that)
return 10;
}
#Override
public int getSpeed() {
return 20*speedFactor(); //this is part of the instance (!!!) therefore it can access speedFactor() protected method too
}
}
package vehicles.main;
public class Main {
public static void main(String[] args) {
AbstractVehicle vehicle = new SedanCar();
int speed = vehicle.getSpeed(); //accessing public method
vehicle.speedFactor(); //cannot access protected method from outside class (in another package)
}
}
The static main() method is not part of the instance, that is why it cannot access the protected method.
The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package.
This is the reason why you can't directly call the method inside the main method on the vehicle object.
See: https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
Subclasses in different package can't access protected methods and protected variables from superclass using superclass reference.
Only way to access protected data of superclass in subclass is through inheritance
below are two code snippets
package nee;
import parentdata.Parent;
class Child extends Parent{
public void testIt(){
System.out.println(x); // able to access protected x defined in Parent
}
}
package nee;
import parentdata.Parent;
class Child extends Parent {
public void testIt(){
Parent p=new Parent();
System.out.println(p.x) // results in compile time error
}
}
In language specification
6.6.2.1 Access to a protected Member
Let C be the class in which a protected member m is declared. Access is permitted only within the body of a subclass S of C. In addition, if Id denotes an instance field or instance method, then:
If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S.
If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.
for in depth details visit
http://www.jot.fm/issues/issue_2005_10/article3.pdf
Back in my SCJP for Java 1.5 days, one thing that I used to remember was be wary of superclass reference variables. It isn't quite as surprising to see this now and one thing why this gets confusing is the rule is protected is visible to subclass or same package. What if it's both subclass and different package?
If you create another package, and do
package yetAnotherPackage;
import car.SedanCar;
public class Main {
public static void main(String[] args) {
new SedanCar().speedFactor();
}
}
you'll see that
The method speedFactor() from the type AbstractVehicle is not visible
Looks like the rule just propagates. As long as you have a subclass and try to access the protected method within the package of the subclass (or if no subclass, then the package of the parent), you should be good.
The following is my ProtectedConstructor.java source code:
package protectCon;
public class ProtectedConstructor{
public int nothing;
ProtectedConstructor(){
nothing = 0;
}
}
And following is the UsingProtectedCon.java source:
package other;
import protectcon.ProtectedConstructor;
public class UsingProtectedCon extends ProtectedConstructor{ //**Line 4**
public static void main(String... a) {
}
}
When I compile UsingProtectedCon.java, I get error at Line 4 shown above. It says that ProtectedConstructor() is not public ; so cannot be accessed outside package.
However, since my class is public, shouldn't I be able to extend it outside package. I am anyway not creating any instance of it.
Now, if I make the constructor of ProtectedConstructor class as public or protected then the code compiles fine with no error.
So then why is it necessary even for the constructor to be public or protected, and not just have default access?
If you want to extends a class outside its package it must have a constructor that is public or protected because in Java every constructor must call a constructor from its superclass.
Because of this there is an implied super() call in every constructor which does not have this() or an explicit call to super() as its first statement. And if you don't specify a constructor at all Java will add a default parameterless constructor, so in effect your code looks like this:
public class UsingProtectedCon extends ProtectedConstructor {
public UsingProtectedCon() {
super();
}
public static void main(String... a) {
}
}
So in other words your code is failing to compile because the call to super() in the default constructor cannot be resolved.
constructor is a member of class like field and method so access modifier applies to it in the same manner it apples to all the member of class
when you extend the class A in B , A's its default constructor will get called from B's constructor implicitly (if you don't call any of the overloaded constructor)
in your class ProtectedConstructor is defined with Package-Private access
This means that outside the package its not seen even by the classes that extend from your ProtectedConstructor class
Define your constructor with 'protected' access modifier instead and you'll be done:
package protectCon;
public class ProtectedConstructor{
public int nothing;
protected ProtectedConstructor(){
nothing = 0;
}
}
Your constructor is not public. Default scope is package-private.
JLS 6.6.7 answers your question. A subclass only access a protected members of its parent class, if it involves implementation of its parent. Therefore , you can not instantiate a parent object in a child class, if parent constructor is protected and it is in different package.Since the default constructor of the subclass would try to call parent class constructor ,you got this error.
See this SO Post for details
to avoid all confusion do it like this.
package protectCon;
public class ProtectedConstructor{
public int nothing;
public ProtectedConstructor(){
nothing = 0;
}
}
package other;
import protectCon.ProtectedConstructor;
public class UsingProtectedCon extends ProtectedConstructor{ //**Line 4**
public UsingProtectedCon(){
super();
}
public static void main(String... a){
}
}
You can have constructors which are public, protected (for internal used) and even private.
A simple example is String which has public constructors for general use and package-local constructors for internal use.
The ObjectOutputStream class has a public constructor which takes an OutputStream and a protected constructor which can only be used by a sub-class.
BTW: if you have an abstract class, does it make sense to make the constructor public as if often the case. ;) hint: it is the same as protected.
If child will have constructor which is private in parent,we can make child's instance with that constructor and cast it to parent's type.
So to prevent this java compiler is not allowing constructor to have constructor which is private in parent.
Given this code snippet, could you explain why it woks?
The thing is that the class constructor is marked private, so should not it prevent us to call it with new operator?
public class Alpha {
protected Alpha() {}
}
class SubAlpha extends Alpha {
private SubAlpha() {System.out.println("ok");}
public static void main(String args[]) {
new SubAlpha();
}
}
It all works because the static method is part of the class and it can see all private fields and methods, right? Outside this "new" initialization would never work?
The only private constructor in your question is SubAlpha, which SubAlpha itself is calling. There's no issue, a class can call its own private methods. The Alpha constructor is protected, so SubAlpha has access to it.
Edit: Re your edit: Yes, exactly. A separate class (whether a subclass or not) would not have access to SubAlpha's private constructor and could not successfully construct a new SubAlpha().
Example 1:
public class Beta
{
public static final void main(String[] args)
{
new SubAlpha();
// ^--- Fails with a "SubAlpha() has private access in SubAlpha"
// compilation error
}
}
Example 2:
public class SubSubAlpha extends SubAlpha
{
private subsubAlpha()
{
// ^== Fails with a "SubAlpha() has private access in SubAlpha"
// compilation error because of the implicit call to super()
}
}
This is, of course, constructor-specific, since scope is always member-specific. If a class has a different constructor with a different signature and a less restrictive scope, then a class using it (including a subclass) can use that other constructor signature. (In the case of a subclass, that would require an explicit call to super(args);.)
The code works as the main method is also in the same class. You may not be able to initialize SubAplha from a different class.
This question already has answers here:
Cannot make a static reference to the non-static method
(8 answers)
Closed 5 years ago.
I'm getting an error when I try to call a non-static method in a static class.
Cannot make a static reference to the non-static method methodName() from the type playback
I can't make the method static as this gives me an error too.
This static method cannot hide the instance method from xInterface
Is there any way to get round calling an non-static method in another static method? (The two methods are in seperate packages and seperate classes).
The only way to call a non-static method from a static method is to have an instance of the class containing the non-static method. By definition, a non-static method is one that is called ON an instance of some class, whereas a static method belongs to the class itself.
You could create an instance of the class you want to call the method on, e.g.
new Foo().nonStaticMethod();
Firstly create a class Instance and call the non-static method using that instance.
e.g,
class demo {
public static void main(String args[]) {
demo d = new demo();
d.add(10,20); // to call the non-static method
}
public void add(int x ,int y) {
int a = x;
int b = y;
int c = a + b;
System.out.println("addition" + c);
}
}
public class StaticMethod{
public static void main(String []args)throws Exception{
methodOne();
}
public int methodOne(){
System.out.println("we are in first methodOne");
return 1;
}
}
the above code not executed because static method must have that class reference.
public class StaticMethod{
public static void main(String []args)throws Exception{
StaticMethod sm=new StaticMethod();
sm.methodOne();
}
public int methodOne(){
System.out.println("we are in first methodOne");
return 1;
}
}
This will be definitely get executed. Because here we are creating reference which nothing but "sm" by using that reference of that class which is nothing
but (StaticMethod=new Static method()) we are calling method one (sm.methodOne()).
I hope this will be helpful.
You need an instance of the class containing the non static method.
Is like when you try to invoke the non-static method startsWith of class String without an instance:
String.startsWith("Hello");
What you need is to have an instance and then invoke the non-static method:
String greeting = new String("Hello World");
greeting.startsWith("Hello"); // returns true
So you need to create and instance to invoke it.
It sounds like the method really should be static (i.e. it doesn't access any data members and it doesn't need an instance to be invoked on). Since you used the term "static class", I understand that the whole class is probably dedicated to utility-like methods that could be static.
However, Java doesn't allow the implementation of an interface-defined method to be static. So when you (naturally) try to make the method static, you get the "cannot-hide-the-instance-method" error. (The Java Language Specification mentions this in section 9.4: "Note that a method declared in an interface must not be declared static, or a compile-time error occurs, because static methods cannot be abstract.")
So as long as the method is present in xInterface, and your class implements xInterface, you won't be able to make the method static.
If you can't change the interface (or don't want to), there are several things you can do:
Make the class a singleton: make the constructor private, and have a static data member in the class to hold the only existing instance. This way you'll be invoking the method on an instance, but at least you won't be creating new instances each time you need to call the method.
Implement 2 methods in your class: an instance method (as defined in xInterface), and a static method. The instance method will consist of a single line that delegates to the static method.
The only way to call a non-static method from a static method is to have an instance of the class containing the non-static method.
class A
{
void method()
{
}
}
class Demo
{
static void method2()
{
A a=new A();
a.method();
}
/*
void method3()
{
A a=new A();
a.method();
}
*/
public static void main(String args[])
{
A a=new A();
/*an instance of the class is created to access non-static method from a static method */
a.method();
method2();
/*method3();it will show error non-static method can not be accessed from a static method*/
}
}
There are two ways:
Call the non-static method from an instance within the static method. See fabien's answer for an oneliner sample... although I would strongly recommend against it. With his example he creates an instance of the class and only uses it for one method, only to have it dispose of it later. I don't recommend it because it treats an instance like a static function.
Change the static method to a non-static.
You can't get around this restriction directly, no. But there may be some reasonable things you can do in your particular case.
For example, you could just "new up" an instance of your class in the static method, then call the non-static method.
But you might get even better suggestions if you post your class(es) -- or a slimmed-down version of them.
The easiest way to use a non-static method/field within a a static method or vice versa is...
(To work this there must be at least one instance of this class)
This type of situation is very common in android app development eg:- An Activity has at-least one instance.
public class ParentClass{
private static ParentClass mParentInstance = null;
ParentClass(){
mParentInstance = ParentClass.this;
}
void instanceMethod1(){
}
static void staticMethod1(){
mParentInstance.instanceMethod1();
}
public static class InnerClass{
void innerClassMethod1(){
mParentInstance.staticMethod1();
mParentInstance.instanceMethod1();
}
}
}
Note:- This cannot be used as a builder method like this one.....
String.valueOf(100);
I use an interface and create an anonymous instance of it like so:
AppEntryPoint.java
public interface AppEntryPoint
{
public void entryMethod();
}
Main.java
public class Main
{
public static AppEntryPoint entryPoint;
public static void main(String[] args)
{
entryPoint = new AppEntryPoint()
{
//You now have an environment to run your app from
#Override
public void entryMethod()
{
//Do something...
System.out.println("Hello World!");
}
}
entryPoint.entryMethod();
}
public static AppEntryPoint getApplicationEntryPoint()
{
return entryPoint;
}
}
Not as elegant as creating an instance of that class and calling its own method, but accomplishes the same thing, essentially. Just another way to do it.
It is not possible to call non-static method within static method. The logic behind it is we do not create an object to instantiate static method, but we must create an object to instantiate non-static method. So non-static method will not get object for its instantiation inside static method, thus making it incapable for being instantiated.
Constructor is a special method which in theory is the "only" non-static method called by any static method. else its not allowed.
You can call a non static method within a static one using:
Classname.class.method()