Contacts

What access modifier can be applied to the package. Access modifiers. Private, protected, default, public. Access control and inheritance

Here we will try to cover almost all cases of using access modifiers. The only exceptions are their use for nested ( nested) and internal ( inner) classes, as well as for interfaces, since we have not yet considered these topics.

Classes and packages used in conjunction with access modifiers serve as encapsulation means, that is, a means of hiding implementation details behind a simple interface.

Access modifiers can be applied to both classes and their members - fields and methods. There are four access modifiers in total, and here we will give a brief description of them, then we will consider each in detail.

  • public- any component declared as public, accessible from any code
  • protected- allows access to the component within the package and classes of descendants
  • private- allows access to components within the class
  • default(no keyword) - Allows access to components within the package

Inherited classes are classes inherited from a class. We haven't studied inheritance yet.

Access to classes

By default, top-level classes are available in the package in which they are defined.... However, if the top-level class is declared as public then it is available everywhere (or wherever the package itself is available). We have limited this statement to top-level classes because classes can be declared as members of other classes. Since these inner classes are members of the class, they obey the rules for controlling access to class members..

Accessing class members

The members of the class are always available inside the body of the class. Default class members are also available in the package in which the class is defined.

Public modifier

For a class that is not nested, only one of two possible access levels can be specified: given default and public . When the class is declared as public, it should be the only one public the class declared in the file and the file name must match the class name.

How public classes, fields, methods and constructors can be declared.

Protected modifier

We'll take a closer look at this modifier in the topic of class inheritance. If inheritance is not used, then this modifier works, just like the default modifier.

The only thing that can be briefly said now is that the components declared as protected will have access any child class from any package or any class from the same package.

How protected fields, methods, constructors, nested classes, and nested interfaces can be declared.

protected .

Private modifier

This is the most restrictive modifier in terms of access restriction. Items declared as private are accessible only within the same class and to no one outside the class.

How private fields, methods, constructors, nested classes and nested interfaces can be declared.

Top-level classes and interfaces cannot be declared as private .

Basically, access modifiers are a simple topic, but we'll come back to them later. While it was just an acquaintance. And now a little practice ...

I created classes Mod02.java, DefMod.java, ProMod.java and PrvMod.java which belong to the pro.java.pkg002 package, as well as the PubMod.java class, which belongs to the pro.java.pkg003 package. Next, I will just give screenshots of these classes and the result of the program:

We will talk about modifiers: what are modifiers, scopes, modifiers for classes, fields, methods. I think it won't be boring.

Modifiers in Java Are keywords that give a class, class field, or method certain properties.

To indicate the visibility of a class of its methods and fields, there are 4 access modifiers:

  • private the members of the class are only accessible within the class;
  • package-private or default (default) class members are visible inside the package;
  • protected class members are available inside the package and in derived classes;
  • public class members are available to everyone.

If you remember, at the end, when we already imported the Cat class, we still had a compilation error.

The thing is that we have not registered any access modifiers to our fields and methods, and they have a default property (class members are visible inside the package). To fix the compilation error for our code and finally run it, we need to make our constructor and methods public. Then they can be called from other packages.

You may start to wonder: what is all this for? Why not make the code visible from any package or class, but need to differentiate access? These questions will disappear on their own when the time comes to write complex and cumbersome projects. Now, when we write applications whose functionality is limited to one or two classes, it seems that it makes no sense to limit anything.

Imagine that you have a class that displays a product object. For example a car. The car may have a price. You have created a price field and many other fields, a bunch of methods that are responsible for the functionality. Everything seems to be good. Your class car is part of a huge project and everyone is happy. But let's say that someone, by mistake or on purpose, instantiated the car class and set a negative price. How can a product have a negative price? This is a very primitive example and is unlikely to happen in real life, but I think the idea is clear. Sometimes you need to give access not directly, but through certain methods. It may be that the code is responsible for the functionality of other code, and you do not want someone to change and edit part of yours. For this all, there is an access restriction.

The access modifier for constructors, methods and fields can be anything. A class can only be either public or default, and there can be only one public class in one file.

For now, there will be enough about access modifiers. In the article "Object Oriented Programming" we will talk about them in more detail, but now let's talk about other modifiers of which, by the way, there are a lot.

Now the next modifier is static... It can be used in front of a method, field, and even a class when we want to declare a nested class. In Java, you can write classes inside other classes, and if the modifier before the class is inside the class static, then such a class is called nested, if there is another modifier or by default, then such a class is called internal. There will be a separate article about nested and inner classes, since everything is not so simple there.

The static modifier in front of a method or field indicates that it does not belong to an instance of this class. What does this mean for us? When we have described a class field or method as static, it can be called without using an instance of the class. That is, instead of this construction: Cat cat = new Cat (); cat.method (), you can just write Cat.method (). Provided that the method is declared static. Static variables are the same for all objects of the class. They have one link.

    public class Modificators (

    static int anotherStaticField = 5;

    public static void myStaticMethod () (

    someField = "My field";

    // nonStaticField = ""; compilation error

    // non-static fields cannot be used

    // in static methods

    public void myNonStaticMethod () (

    anotherStaticField = 4; // static fields can be used

    // in non-static methods

    // main method also has a static modifier

    new Modificators () .myNonStaticMethod ();

    Modificators.myStaticMethod (); // call static methods and fields

    // via classname.method

Another important thing to note about static modifiers is that static fields are initialized at class load time. Often in various kinds of Java tests, you can find the following code:

Question: what will be displayed on the console? It should be remembered that the static block will be displayed first in any case. Next will be the default block. Next, look at the console screen:

The next modifier we'll look at will be final.

I think the word final speaks for itself. By applying the final modifier, you say that fields cannot be changed, methods are overridden, and classes cannot be inherited (there will be a separate article on inheritance). This modifier applies only to classes, methods, and variables (also to local variables).

We will talk about the final modifier to methods and classes in the OOP article.

Next, there will be modifiers that will not be very clear for beginners or those who read this series of articles from scratch. And although I still cannot explain everything to you (due to the fact that you do not know the accompanying material), I still advise you to just familiarize yourself with them. When it comes time to use these modifiers, you will already understand most of the terms used below.

Modifier synchronized- indicates that the method can be used by only one thread at a time. While this may not tell you anything, the usefulness of this modifier will be seen as we learn about multithreading.

Modifier transient- says that during the serialization of the object, some field should be ignored. Typically, these fields store intermediate values.

Modifier volatile- used for multithreading. When a field with the volatile modifier will be used and changed by multiple threads, this modifier ensures that the field will change in turn and there will be no confusion with it.

Modifier native before the method declaration indicates that the method is written in another programming language. Usually in C.

Modifier strictfp- Provides performance of operations on numbers of type float and double (floating point) according to the IEEE 754 standard. Or, more simply, guarantees that within a method the results of calculations will be the same on all platforms.

I haven't talked about the modifier yet abstract... I will tell you about it in a nutshell, because without knowledge of the basics of object-oriented programming, I see no point in talking about it.

A class that has the abstract modifier cannot be instantiated. The only purpose for it is to be expanded. An abstract class can contain both abstract methods as well as ordinary ones.

We will talk more about the abstract modifier in the OOP article.

This concludes the article on modifiers. Much has not been said about them. But this is due to the fact that we do not have OOP concepts yet. In a few more articles, we will expand on modifiers and fill in the blanks.

First, let's take a look at the access modifiers. There are only four of them:

  • private class members are only accessible inside the class
  • package-private or default (default) class members are visible inside the package
  • protected class members are available inside the package and in derived classes
  • public class members are available to everyone

During inheritance, it is possible to change access modifiers towards GREATER visibility.

The access modifier for constructors, methods and fields can be any, but with classes and their blocks it's not so simple. A class can only be either public or default, and there can be only one public class in one file. A block can have only one modifier - default.

Static, abstract and final modifiers

Static

  • Applies to inner classes, methods, variables and logical blocks
  • Static variables are initialized at class load time
  • Static variables are the same for all objects of the class (same reference)
  • Static methods only have access to static variables
  • Static methods and variables can be accessed through the class name
  • Static blocks are executed at class load time
  • Non-static methods cannot be overridden as static
  • Local variables cannot be declared static
  • Abstract methods cannot be static
  • Static fields are not serialized (only when implementing the Serializable interface)
  • Only static class variables can be passed to the constructor with parameters, called via the word super (// parameter //) or this (// parameter //)

Abstract

  • Applies only to methods and classes
  • Abstract methods have no method body
  • It is the opposite of final: a final class cannot be inherited, an abstract class must inherit
  • A class must be declared abstract if:
  1. it contains at least one abstract method
  2. it does not provide an implementation of inherited abstract methods
  3. it does not provide an implementation of the methods of the interface, the implementation of which it has declared
  4. it is necessary to prohibit the creation of instances of the class

Final

  • Fields cannot be changed, methods are overridden
  • Classes cannot be inherited
  • This modifier only applies to classes, methods and variables (also to local variables)
  • Method arguments marked as final are read-only, there will be a compile-time error when trying to modify
  • Final variables are not initialized by default, they must be explicitly assigned a value when declared or in a constructor, otherwise - a compilation error
  • If the final variable contains a reference to an object, the object can be modified, but the variable will always refer to the same object
  • This is also true for arrays, because arrays are objects, an array can be changed, and a variable will always refer to the same array.
  • If the class is declared final and abstract (mutually exclusive concepts), a compilation error will occur
  • Since a final class cannot be inherited, its methods can never be overridden.
Constructor cannot be static, abstract or final

The strictfp, transient, volatile, synchronized, native modifiers

Strictfp

  • Applies to methods and classes
  • Provides operations on float and double (floating point) numbers according to the IEEE 754 standard

Transient

  • Only applicable for class level variables (local variables cannot be declared as transient)
  • Transient variables may not be final or static.
  • Transient variables are not serialized

Volatile

  • Used with variables only
  • Can be used with static variables
  • Not used with final variables - The value of a variable declared as volatile changed by one thread is changed asynchronously for other threads
  • Used in multi-threaded applications

Synchronized

  • Applies only to methods or method parts
  • Used to control access to important parts of the code in multithreaded programs

Native

  • Used only for methods
  • Indicates that the method was written in another programming language
  • Classes in Java use many native methods to improve performance and hardware access
  • It is possible to pass / return Java objects from native methods
  • Method signature must end with “;”, curly braces will cause compilation error

Features in interfaces

  • Methods are always public and abstract, even if not declared
  • Methods cannot be static, final, strictfp, native, private, protected
  • Variables are only public static final, even if not declared
  • Variables cannot be strictfp, native, private, protected
  • Can only inherit (extends) another interface, not implement an interface or class (implements).

Let's put all the modifiers together:

Class

Inner class

Variable

Method

Constructor

Logic block

public

Yes

Yes

Yes

Yes

Yes

No

protected

No

Yes (except for local and anonymous classes)

Yes

Yes

Yes

No

default

Yes

Yes

Yes

Yes

Yes

private

No

Yes (except for local and anonymous classes)

Yes

Yes

Yes

No

final

Yes

Yes (and for a local variable)

Yes

No

No

abstract

Yes

Yes (except for anonymous classes)

No

Yes

No

No

static

No

Yes (except for local and anonymous classes)

Yes

Yes

No

Yes

native

No

No

No

Yes

No

No

transient

No

No

Yes

No

No

No

synchronized

No

No

No

Yes

No

Yes (only as part of the method)

volatile

No

No

Yes

No

No

No

strictfp

Yes

Yes

No

Yes

No

No

5

I've seen some discussion on StackOverflow about this topic, but I don't see something that helped me understand the following point:

I come from a C ++ background and recently I started learning Java. In C ++, when protected, only a subclass is used that can access the member (analogous to a field in Java).

There are also friend classes in C ++ that can access the class's private / protected cameras, which give friendship. This is a bit like the "package" field modifier in Java (the default field modifier), except that in C ++, friendship gives access to all private members, but in Java, access from classes in one package is specific to the class field.

What I can't figure out, assuming I only want to provide access to subclasses, is what I can do in C ++ by declaring protected members on a class that doesn't "give" friendships.

But in Java I don't know how to do this, because with the help of a "protected" field modifier - I also provide access to all the classes in the package. The only way I find it is to declare a protected field and isolate the class in its package.

From this I conclude that grouping classes into one package should be done based on the "friendship" between the classes. Is this really the leading factor when bundling packages?

Another thing I don't understand, In Java, assuming I have two fields in class A: b, c. I want to give B access to b but not to, and I want to give C access to c but not b. and to "Peace" I want b, c to hide. How can I do that? I am assuming that B, C should be in the same package as A. but by declaring b, c with package with modifier I allow B, C access to both b and. Is there a way in Java to do this?

Hope for some explanation of this question

11

A better question, if less useful, will be narrower and more specific. The general question "everything about privacy in Java and C ++ and how they differ" is more than too broad. Can you ask a more specific question about a more specific problem? - Yakk 04 Mar 15 2015-03-04 16:38:58

  • 4 answers
  • Sorting:

    Activity

2

In C ++, when security is used, only the subclass can access the element (analogous to a field in Java).

Access specifiers are also for member functions / methods, not just member variables.

In C ++ there are also "friend" classes that can access the private / protected mambers of the class, which gives "friendship". This one is a bit like the "package" field modifier in Java (the default field modifier), except that in C ++, friendship gives access to all private members, but in Java, access from classes in the same package is specific to the class field.

There are not only friend classes, but also functions.

It is true that accessing Java private parts is similar, but it is not a complete replacement. Better to say that these two functions have subset the problems they solve. There are problems that can be solved by a friend, but not by a private package, and vice versa.

What I couldn't figure out, assuming that I only want to provide access to subclasses, is what I can do in C ++ by declaring users protected in a class that friendship doesn't "give".

But in Java, I don't know how I can do this,

Answer: You cannot.

since with the help of a "protected" field modifier - I also provide access to all the classes in the package.

The only way I can find is to declare a protected field and have the class isolated in its package.

Technically, yes. But this creates other problems. Your class will no longer be able to access the private package parts of its previous package. Let's say your BaseClass was at com.example.one. You will move it to com.example.two. Now it will no longer be able to access other com.example.one private class packages.

Is this really the leading factor when bundling packages?

Yes, Java is designed that way. You can try fight the rules of the language but it's a losing battle in any programming language.

Another thing I don't understand in Java, assuming I have two fields in class A: b, c. I want to give B access to b but not to, and I want to give C access to c but not b. and in "World" I want b, c to hide. How can I do that?

It cannot be done in a clean way (clean I mean: without any hacks that would require you to check the call stack at runtime and throw exceptions).

If you are concerned about this scenario because you are developing a public API, a low-tech solution that usually works great is to create one or more * .internal packages and clearly document the fact that they should not be used in client code.

1

That's quite a bunch of questions together ...

But in Java, I don't know how I can do this, since by virtue of using a "protected" field modifier - I also provide access to all the classes in the package.

Indeed, there is no way to provide access to only subclasses, but not classes in the same package. It was a design decision made centuries ago ...

The only way I find it is to declare a protected field and isolate it in my package.

This is technically correct, although it will be of little use. Class wrapping is for grouping related classes, where "siblings" means "classes that fulfill a particular relationship," i.e., they belong to the same use case, belong to the same architectural level, are in the same entities, etc.

From this I conclude that grouping classes into one package should be done based on the "friendship" between the classes. Is this really the leading factor when bundling packages?

I believe I already answered this in the previous paragraph: packaging is for grouping related classes according to some specific criteria.

For your A, B and C classes, for example with attributes:

I think B, C should be both in the same package, A declaring b, with packing modifier I let B, C access both b and k. Is there a way in Java to do this?

The answer is no, there is no easy, clean way to do this. You could achieve this with some hacks or more advanced techniques, but again, this was part of the decisions made by the language designers a long time ago ...

0

Short answer: there is no way to do this.

If you are worried about intrusion from injecting class clients in a package to get unauthorized access, you can move the sensitive code in a separate package, and make the package sealed in a jar you deliver it to: http://docs.oracle.com/javase/tutorial /deployment/jar/sealman.html

1

It is implicitly assumed that all classes in a package "know" each other (because they were written by the same person / company / organization). This way, they either don't get access to the protected fields, or if they do, they know how to do it properly.

The classes in the same package are assumed to be more related to each other than the parent is to the derived class, because the derived class might actually be written by someone else. So they decided that private protection was more limited than protected.

So, I guess you don't have to worry about how classes in the same package can access each other's fields. In general, I just don't use this function, except when I write iterators.

If you have two fields, you can make them inner classes so that they have access to private fields (again, logic: if a class is inside another class, it knows about the semantics of that class) and can expose that access to their derived classes through protected methods.

You can of course come up with a complex token exchange protocol to make this field only accessible to B / C instances, but that would be a wonderful overhead and another object can still use reflection to access all private members if you don't disable it using security policies, which is usually not the case, but again, security policies are ultimately decided by the owner of the JVM.

So, ultimately the preferred way to do what you say in Java is to either put them in the same package or write B and C as inner classes of A so that they can directly access the private members of A and expose them derived classes.

Public class A (public static abstract class B (protected Whatever getWhatever (A a) (return ab;) protected void setWhatever (A a, Whatever value) (ab = value;)) public static abstract class C (protected Whatever getWhatever (A a) (return ac;) protected void setWhatever (A a, Whatever value) (ac = value;)) private Whatever b; private Whatever c;)

once again, you always think that classes in the same package will never do anything wrong.

Last update: 03.10.2019

All members of a class - fields, methods, properties - they all have access modifiers... Access modifiers allow you to set a valid scope for class members. That is, access modifiers define the context in which a given variable or method can be used. In previous topics, we have already encountered it when we declared class fields to be public (that is, with the public modifier).

The following access modifiers are used in C #:

    public: a public, public class, or a member of a class. Such a class member is accessible from anywhere in the code, as well as from other programs and assemblies.

    private: a private class or member of a class. Represents the exact opposite of the public modifier. Such a private class or class member is only accessible from code in the same class or context.

    protected: Such a class member is accessible from anywhere in the current class or in derived classes. However, derived classes can be located in other assemblies.

    internal: a class and members of a class with a similar modifier are accessible from anywhere in the code in the same assembly, but it is not available to other programs and assemblies (as is the case with the public modifier).

    protected internal: combines the functionality of two modifiers. Classes and class members with this modifier are available from the current assembly and from derived classes.

    private protected: Such a class member is accessible from anywhere in the current class or in derived classes that are defined in the same assembly.

We can explicitly set the access modifier, for example:

Private protected class State (internal int a; protected void Print () (Console.WriteLine ($ "a = (a)");))

Or we can skip specifying:

Class State (int a; void Print () (Console.WriteLine ($ "a = (a)");))

If no access modifier is defined for fields and methods, the private modifier is used for them by default.

Classes and structures declared without a modifier have internal access by default.

All classes and structures that are directly defined in namespaces that are not nested within other classes can only have public or internal modifiers.

Let's look at an example and create the following State class:

Public class State (// is the same as private int defaultVar; int defaultVar; // the field is accessible only from the current class private int privateVar; // accessible from the current class and derived classes that are defined in the same project protected private int protectedPrivateVar; // available from the current class and derived classes protected int protectedVar; // available anywhere in the current project internal int internalVar; // available anywhere in the current project and from inherited classes in other projects protected internal int protectedInternalVar; // available in anywhere in the program, as well as for other programs and assemblies public int publicVar; // has a modifier by default private void defaultMethod () => Console.WriteLine ($ "defaultVar = (defaultVar)"); // the method is accessible only from the current class private void privateMethod () => Console.WriteLine ($ "privateVar = (privateVar)"); // accessible from the current class and derived classes that are defined in the same paragraph protected private void protectedPrivateMethod () => Console.WriteLine ($ "protectedPrivateVar = (protectedPrivateVar)"); // accessible from the current class and derived classes protected void protectedMethod () => Console.WriteLine ($ "protectedVar = (protectedVar)"); // available anywhere in the current project internal void internalMethod () => Console.WriteLine ($ "internalVar = (internalVar)"); // available anywhere in the current project and from inherited classes in other projects protected internal void protectedInternalMethod () => Console.WriteLine ($ "protectedInternalVar = (protectedInternalVar)"); // available anywhere in the program, as well as for other programs and assemblies public void publicMethod () => Console.WriteLine ($ "publicVar = (publicVar)"); )

Since the State class is declared with the public modifier, it will be accessible from anywhere in the program, as well as from other programs and assemblies. The State class has five fields for each access level. Plus one variable without a modifier, which is private by default.

There are also six methods that will display the values ​​of the class fields on the screen. Please note that since all modifiers allow you to use class members inside this class, then all class variables, including private ones, are available to all of its methods, since they are all in the context of the State class.

Now let's see how we can use the variables of our class in the program (that is, in the Main method of the Program class), if the State and Program classes are in the same project:

Class Program (static void Main (string args) (State state1 = new State (); // we will not be able to assign the value to the defaultVar variable, // since it has a private modifier and the Program class does not see it // And the environment will underline as incorrect state1.defaultVar = 5; // Error, you cannot get access // The same applies to the privateVar variable state1.privateVar = 5; // Error, you cannot get access // assign the value of the protectedPrivateVar variable will not work, // since the Program class is not a subclass of the State class state1.protectedPrivateVar = 5; // Error, you cannot get access // assign the value of the protectedVar variable will also fail, // since the Program class is not a subclass of the State class state1.protectedVar = 5; // Error, you cannot get access // the internalVar variable with the internal modifier is accessible from anywhere in the current project // therefore, safely assign it the value state1.internalVar = 5; // the protectedInternalVar variable is also accessible from anywhere in the current project state1.protectedInternalVar = 5; // publicVar is publicly available state1.publicVar = 5; ))

Thus, we were able to set only the variables internalVar, protectedInternalVar and publicVar, since their modifiers allow us to use them in this context.

The situation is similar with the methods:

Class Program (static void Main (string args) (State state1 = new State (); state1.defaultMethod (); // Error, cannot be accessed state1.privateMethod (); // Error, cannot be accessed state1.protectedPrivateMethod () ; // Error, you cannot get access state1.protectedMethod (); // Error, you cannot get access state1.internalMethod (); // norms state1.protectedInternalMethod (); // norms state1.publicMethod (); // norms))

Here, only three methods were available to us: internalMethod, protectedInternalMethod, publicMethod, which have the internal, protected internal, and public modifiers, respectively.

Thanks to such a system of access modifiers, it is possible to hide some aspects of the class implementation from other parts of the program.

Despite the fact that the public and internal modifiers are similar in their action, they have a big difference. Classes and members of the class with the public modifier will also be available to other programs if the given class is placed in the dynamic library dll and then used in these programs.



Did you like the article? Share it