Package Private Class

Package Private Class




⚡ 👉🏻👉🏻👉🏻 INFORMATION AVAILABLE CLICK HERE 👈🏻👈🏻👈🏻




















































I’ve written before about the benefits of using PHP’s Anonymous Classes for test doubles; but Anonymous Classes also have potential usecases within production code as well. In this article I’m going to describe one such usecase that can be particularly useful within libraries, and that is replicating the access of Package Private (in Java), or Protected Internal Classes (as per C#).
In Java, a Package Private class will be accessible to other classes in the same package but will be inaccessible to classes outside the package, meaning that it isn’t possible to create an object of that class or to declare a variable of that class type. In C#, Internal or Protected Internal Classes enable a group of components to cooperate in a private manner without being exposed to the rest of the application code. Access to Internal Classes is limited to the assembly in which they exist, or can be granted to specific “friend” assemblies.
This class visibility simply in’t available in PHP, but it could be useful for library writers to have that control over visibility of the classes inside their packages that are only intended for internal use.
My own usecase (with the PHPExcel/PHPSpreadsheet libraries as an example) for Package Private classes is based around the fact that a worksheet object contains a collection of cell objects, and a cell object should only be created using the appropriate getCell() method in the worksheet object, because this ensures that the connection between the two is correctly established. While most users of the library do build their spreadsheets correctly using the getCell() method as per the documentation, the existence of a Cell class within the library means that some users of the library mistakenly believe that they can instantiate a cell from within their own code, which has no connection to any worksheet object, and wonder why things don’t work as they expected… and there is no mechanism built into PHP itself that I can use to prevent them from doing so.
So what I want to achieve in PHP is a class with all its public methods still accessable from within userland code, so that the developer using the library can still read and set values and styling using the cell object’s public methods; but that cannot be instantiated from outside the library. It doesn’t exactly match Java’s Protected Private or C#’s Protected Internal; but in the absence of any class visibility within PHP, it’s the closest approximation that I’ve managed to achieve.
Let’s start with some example code, cell and worksheet class definitions.
And the documented process to create a new cell is through the call to the worksheet’s getCell() method using
But there is nothing to prevent somebody using
to instantiate a new cell object, but without that entry in the worksheet’s collection.
So let’s rewrite this with cell as an abstract class, so it cannot be instantiated directly, and then modify the getCell() method to create an anonymous class extending that abstract instead.
Externally, we create a new cell in the worksheet in exactly the same way. From code outside the library, the only way to instantiate a cell object is by calling the getCell() method of the worksheet object — we can no longer use $cellA1 = new cell('A1', 10); because this will give a Fatal Error — or by explicitly writing a new concrete class (or another anonymous class) that extends the cell class and instantiating that. Neither of these could be considered a mistake; but rather it requires a conscious decision on the part of the developer using the library.
The difference now is that the cell object is of an anonymous class, but one that extends cell, so all the public methods defined in the abstract class are still accessible in userland code, and we can still typehint as an object of type cell.
Of course, there are limitations to using Anonymous Classes, and these can cause complications. For example, PHPExcel needs to be able to serialize cell objects when it uses cell caching, but it isn’t possible to serialize an instance of an anonymous class, even if it implements Serializable or has the magic __sleep()/__wakeup() methods defined. Attempting to serialize() an anonymous class will always throw an Exception.
But that doesn’t prevent us from writing our own serialize()/unserialize() methods; although we have to call them manually. For this we’ll use a Trait:
And apply it directly against our Anonymous Class rather than the abstract cell class, modifying the worksheet’s getCell() method to apply the Trait:
Applying the serialize()/unserialize() methods to the Anonymous Class means that they’re not part of the public documentation for the cell, so library users shouldn’t be tempted to call them from their own code.
Of course, we do need to create a new cell through the worksheet getCell() method before we can unserialize the data to it, so internally we need to keep track of the details so that we match up the correct address reference; but as we’re only utilising serialize()/unserialize() from within our library code, we should be able to do so. We would also need to provide a custom magic __sleep()/__wakeup() in the worksheet class if we wanted to allow that to be serializable as well.
I’ve kept the class properties in this example simple too, so they are all protected rather than private, and all of them are instance properties rather than static properties, purely so I can provide a simple demonstration of the serialize()/unserialize() methods. If there were private cell properties or statics involved, then I’d need to provide a more complex mapper for those methods.
While I can resolve the issue of serialization, another drawback is that IDEs like PHPStorm no longer hint at the methods and properties of a cell object because it’s no longer an instance of class cell, but of the Anonymous Class, and even though this extends cell, the IDE doesn’t recognise this. If you’re working purely with an internal library class, where there should be no external access to the properties or methods, this may be less of a problem (though it is still awkward when working with an IDE); but if those methods need to be publicly available, and it’s only class instantiation that you want to control, then this approach probably isn’t recommended as a solution.
This is simply a proof of concept rather than a planned change to the PHPExcel or PHPSpreadsheet libraries; nor is it a definitive solution to implementing private classes within a library (core PHP functionality would be a far better option were it available). Rather, it is a demonstration of how anonymous classes could be used to create internal library classes, and some of the limitations with doing so.
This entry was posted in PHP and tagged Anonymous, Class, Internal, PHP, Private. Bookmark the permalink.
Clever, but an abstract protected class is also part of your public API – it’s literally an invitation to extend the class, at which point protected methods are part of your public API as well.
To my knowledge, the closest thing we have in PHP today, is the @internal doc-block – I guess, in cases like this one, you might also get away with completely hiding an anonymous class inside a private static method. But it does start to look a bit like mangling the code to try to get something that PHP just doesn’t really offer at this time.
You could always add a final annotation with “use at own risk”. Not perfect, but it’s something.
/** @final do not extend, use at own risk */
abstract class Foo {}
to avoid this “abstract class invitation” at all, maybe it is possible to just create the whole Cell class as an anonymous class, without extending?
Or justt use and interface that you implement in the anonymous class
Your email address will not be published. Required fields are marked *
Notify me of new comments via email.
Already have a WordPress.com account? Log in now.

Sign up or log in to view your list.
I was playing around with JShell after the Java 9 release, and I tried importing a package I made. As the entire application I'm coding it for will be contained in that package, every class but one (which I haven't coded yet) is package-private. My classpath is correct, but I still can't use any of the types declared in the package in JShell (it throws a "cannot find symbol" error). Do I need to make them public for them to be accessible, or is there some way I can test package-private classes? Here's the exact code I tried.
and the package directory (for the bytecode) is
CollatzSequence is a package-private class contained in collatz.
Isaac Saffold
Isaac Saffold 986●11 gold badge●88 silver badges●1818 bronze badges
Could you please share a reproducible code for the scenario? That would help make the question clear. – Naman Sep 24 '17 at 19:17
I just included it in my edit. – Isaac Saffold Sep 25 '17 at 18:14
As far as i know (correct me if i am wrong), you cannot create a Class in a specific package using JShell (classes created within JShell are always in the default package).
That being said, you cannot access your package-private classes from within JShell. This is "normal" Java behaviour.
rmuller
rmuller 10.3k●44 gold badges●5454 silver badges●8181 bronze badges
Regarding creating a class in a specific package, I couldn't find a way to do so with JShell commands, and it otherwise makes sense that you wouldn't be able to do so, but I don't know for sure. And I suppose not being able to access package-private classes makes sense as well, but it's a huge disappointment. – Isaac Saffold Sep 25 '17 at 18:22
A snippet may not declare a package or a module. All JShell code is placed in a single package in an unnamed module. The name of the package is controlled by JShell.
That is the reason probably why you are not able to declare a package within JShell.
As the tool documentation suggests though you can give this a try:-
The default startup script consists of several common imports. You can personalize your startup entries with the /set start command.
where you can set the classpath or the modulepath of the class you would make use of :
Naman
Naman 18k●2323 gold badges●179179 silver badges●302302 bronze badges
Very useful information, but I'm not trying to declare a new package; I'm trying to access package-private classes in an existing one. My class path already points to the correct directory, but I'll try explicitly setting it in the shell. However, I think the accepted answer is right; only public classes are accessible to JShell. – Isaac Saffold Sep 25 '17 at 22:22
Click here to upload your image (max 2 MiB)
You can also provide a link from the web.
By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy
2021 Stack Exchange, Inc. user contributions under cc by-sa
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
Accept all cookies Customize settings

Hot Squirting Compilation
Xnxx Japan Kino
Mistress Sidonia Piss
Mom Fuck Daughter Strapon
Wife Rio 2021
Using PHP Anonymous Classes as Package Private Classes ...
java - Importing Package-Private Classes to JShell - Stack ...
What is the difference between public, protected, package ...
Private class package - Food and Alcohol Safety ...
java - StringUTF16 публичные методы в package-private ...
Private class in java - W3spoint
Модификаторы доступа public, protected и private в Java ...
Private Class Packages - Zabaan School for Languages
Why you should avoid package-private scope in Java - DEV ...
Package Private Class


Report Page