package visibility [closed]

2019-02-22 07:05发布

Why use package visibility (the default), unless the class should be public in java

3条回答
Juvenile、少年°
2楼-- · 2019-02-22 07:30

What you get by default modifier i.e, without any access modifier (ie, public private or protected),it means that it is visible to all within a particular package. So, when you want your class to be accessible only in its own package, you should go for the default one.

Read more : Controlling Access

查看更多
SAY GOODBYE
3楼-- · 2019-02-22 07:32

My understaning is package/default access is for package internals, i.e. classes that do not form package interface, i.e. classes that should not be used outside the package.

查看更多
来,给爷笑一个
4楼-- · 2019-02-22 07:46

As Rostislav Matl said, it's useful for when you want to make something that doesn't form part of your package's interface.

As an example, imagine you have a package and it provides an interface and at least one concrete implementation of a service.

People who use this service are going to care about the interface you provide and use one of the concrete classes you provide but they aren't going to care about much else beyond that. Our service has to talk to a database and it needs to be able to map the result from database queries into its own data type (that form its contract).

I find that I regularly create package private helper classes that contain utility type methods or perform tasks like the mapping that we need. Default (package private) visibility is perfect for this because other classes inside your package can use these helpers but no-one outside the package can see them so you're free to change them whenever you like.

This is a an example using some code:

We have our interface:

public interface UsefulService {
    Collection<DataThings> getThings(Identifier id);
}

...and our concrete implementation:

public class JdbcUsefulServiceImpl implements UsefulService {

     //We can break the code for the mapping out into its own class
    private Mapper mapper;

    @Override
    public Collection<DataThings> getThings(Identifier id){
        DatabaseQueryResult queryResult = //Code to hit a database and return objects from that domain model
        Collection<DataThings> result = mapper.mapFromDatabaseToServiceDomain(queryResult);
        return result;
    }
}

Then we have our mapper. We don't need anyone outside the package to care about the service works internally so we use package private visibility and we can have as many classes as we want to get the job done:

class Mapper {
    Collection<DataThings> mapFromDatabaseToServiceDomain(DatabaseQueryResult queryResult){
        //magic to map objects goes here
    }
}

The benefit that we have is that we can always change this Mapper class however we want or delete it or create new package private classes and we know the only (immediate) effects we can cause are inside this package. By immediate effects I mean compiler errors and serious things like that. Obviously you could break your service if you change its behaviour but that's what your automated test suite is there to catch :P

查看更多
登录 后发表回答