Interface visibility restriction, but runs fine - java

When designing a fluid API, sometimes I want to use Interface return types so that the caller can easily follow the available methods or gets compiler errors if he does not (the Step Builder pattern is an example).
But when I want to use interfaces just to point to the next available method, like:
package packageone;
public class SomeClass implements CanPrint {
private SomeClass() {
}
public static CanPrint get() {
return new SomeClass();
}
#Override
public void print() {
System.out.println("Runs fine!");
}
}
public interface CanPrint {//Compile error: must be defined in own file
public void print();
}
However, firing up a quick test works fine (the following code prints "Runs fine!"):
package packagetwo;
import packageone.CanPrint;
import packageone.SomeClass;
public class Main {
public static void main(String[] args) {
CanPrint returnType = SomeClass.get();
returnType.print();
}
}
The compiler can be 'fooled' by wrapping the entire class:
package packageone;
public class Wrapper {
public static CanPrint get() {
return SomeClass.get();
}
public static class SomeClass implements CanPrint {
public static CanPrint get() {
return new SomeClass();
}
private SomeClass() {
}
#Override
public void print() {
System.out.println("Runs fine!");
}
}
public interface CanPrint {
public void print();
}
}
So currently when I want to keep the interfaces in the same place as the only code that is intended to use it (as the caller only needs the method), I wrap it in a wrapper class which only points to the same method in the inner class.
Why is this restriction in place? The other class can import the interface, use it, even implement their own version if they desire to do so. All of this seems to run without problems. Yet it does not compile.
Note: I've simplified my examples as much as I could, but because of this it might be less clear why one would choose this design.

Why is this restriction in place?
It makes it easier for the compiler and humans to find the source file containing a top-level class.
You can expose the interface by:
Placing the interface in a separate file, like ISomeClassCanPrint.
Or nesting the interface in the class that returns an instance. Your wrapper is close to this approach.
Here's another example of a nested interface:
public static class SomeClassFactory {
public interface CanPrint {
public void print();
}
public static CanPrint get() {
return new SomeClass();
}
public static class SomeClass implements CanPrint {
#Override
public void print() {
System.out.println("Runs fine!");
}
}
}
More detail
The restriction is covered by the Java Language Specification, section 7.6: Top level type declarations:
If and only if packages are stored in a file system (ยง7.2), the host system may choose to enforce the restriction that it is a compile-time error if a type is not found in a file under a name composed of the type name plus an extension (such as .java or .jav) if either of the following is true:
The type is referred to by code in other compilation units of the package in which the type is declared.
The type is declared public (and therefore is potentially accessible from code in other packages).
This restriction implies that there must be at most one such type per compilation unit. This restriction makes it easy for a Java compiler to find a named class within a package. In practice, many programmers choose to put each class or interface type in its own compilation unit, whether or not it is public or is referred to by code in other compilation units.
So while you are allowed to declare multiple top-level classes in a single file, at most one can be exposed for access outside the file.
You can, however, expose as many nested classes as you want.

Related

What is the purpose of a static method in interface from Java 8?

Why are static methods supported from Java 8? What is the difference between the two lines in main method in below code?
package sample;
public class A {
public static void doSomething()
{
System.out.println("Make A do something!");
}
}
public interface I {
public static void doSomething()
{
System.out.println("Make I do something!");
}
}
public class B {
public static void main(String[] args) {
A.doSomething(); //difference between this
I.doSomething(); //and this
}
}
As we can see above, I is not even implemented in B. What purpose would it serve to have a static method in an interface when we can write the same static method in another class and call it? Was it introduced for any other purpose than modularity. And by modularity, I mean the following:
public interface Singable {
public void sing();
public static String getDefaultScale()
{
return "A minor";
}
}
Just to put like methods together.
In the past, if you had an interface Foo and wanted to group interface-related utils or factory methods, you would need to create a separate utils class FooUtils and store everything there.
Those classes would not have anything in common other than the name, and additionally, the utils class would need to be made final and have a private constructor to forbid unwanted usage.
Now, thanks to the interface static methods, you can keep everything in one place without creating any additional classes.
It's also important to not forget all good practices and not throw everything mindlessly to one interface class - as pointed out in this answer
There are mainly two reasons for static method inside interfaces: create instances of those interfaces (and the code is clearly where it has to be); like Predicate::isEqual that would create a Predicate based provided Object; or Comparator::comparing, etc. And the second reason would be utility methods that are general per all those types; like Stream::of
Still an interface has to be clear and does not have to create additional clutter in the API. Even the jdk code has Collectors - static factory methods, but a Collector interface at the same time for example. Those methods could be merged into Collector interface, but that would make the interface more clunky than it has to be.

Why am I able to have a public member in a non-public class?

class MyClass
{
public static final int num=90;
}
Why am I allowed to create a public member in a non-public class?
Is there another way of accessing this member that I do not know of (other than through the class name)?
Since your question was about members, I will address both fields and methods (non-static; Anthony Accioly's answer touches on another good use case, which also includes static fields).
While in many situations this is just an ambiguous consequence of the language's grammar (in particular: public fields in non-public classes, as in your example snippet), there are very good reasons for needing to be able to use public methods in non-public classes.
Expanding on Mik378's answer, consider, e.g., the following (contrived example):
import ...;
class BleebleAscendingComparator implements Comparator<Bleeble> {
#Override public int compare (Bleeble o1, Bleeble o2) { ... }
}
class BleebleDescendingComparator implements Comparator<Bleeble> {
#Override public int compare (Bleeble o1, Bleeble o2) { ... }
}
public class BleebleView {
public enum SortMode { ASC, DESC };
public Comparator<Bleeble> getDisplayOrderComparator (SortMode mode) {
if (mode == SortMode.ASC)
return new BleebleAscendingComparator();
else
return new BleebleDescendingComparator();
}
}
You cannot instantiate one of those Comparator implementations directly outside of that context, but they must override public methods of Comparator, and their functionality is accessible via a Comparator interface.
This same reasoning applies to, e.g., private or protected inner classes. If you were not able to declare methods public, you would have no way of overriding public methods of interfaces that they inherit or classes that they extends.
Practical Examples:
You use this every time you override a public method in an anonymous inner class (e.g. every time you override public void actionPerformed in an anonymous ActionListener).
Consider any non-public class that you would like to store in a HashMap. You would override the public equals() and hashCode() in that non-public class, and the implementation of HashMap can access them regardless of the fact that the class is non-public.
The often overridden public toString() is another common example of a public member of a potentially non-public class.
A more complex example is the use of java.sql.Driver in java.sql.DriverManager (in general, factory-type designs make heavy use of this concept) -- an SQL driver implementation may not make implementation classes public (e.g. the Oracle driver produces non-public Connection objects).
Many more... if you keep an eye out for examples of this, you'll be surprised how common it really is!
Don't forget that classes with default access can be subclassed by public classes in the same package.
package package1;
class MyDefaultClass {
public static final int MY_CONSTANT = 0xCAFEBABE;
}
public class PublicExporter extends MyDefaultClass {
}
Now the public class acts as a bridge, and you are able to consume MyDefaultClass public members from other packages.
package package2;
import package1.PublicExporter;
public class Consumer {
public static void main(String[] args) {
System.out.printf("%x\n", PublicExporter.MY_CONSTANT);
}
}
Consumers can even import static members:
import static package1.PublicExporter.MY_CONSTANT;
public class Consumer {
public static void main(String[] args) {
System.out.printf("%x\n", MY_CONSTANT);
}
}
When a public method belonging to an enclosing class A returns a reference (public supertype reference, like an interface) to its inner class B having default scope, external client (outside A's package) can only call B's methods but can't CREATE themselves fresh instances of B.
If the B's methods weren't public, external client couldn't reach them, and worse: would cause a compilation error since not well implementing its interface.
This modeling could be useful in a certain context, to improve code design.
When you declare a variable public it essentially becomes exactly that ; it's able to be seen throughout your entire program, without any special getters/setters. The class does not necessarily need to be public in order for its members to be public also.
Remember, in Java you can only have 1 public class per compilation unit( .java file), and that public class needs to have the same name as the compilation unit. Other than that, it doesn't "own" ownership of the keyword public.
The fact that you declared num as public and static allows you to say System.out.println(MyClass.num). The public attribute allows you to get the num variable directly. Thus, you do not have to create a method to return num for you. Because it is public, you can also say
MyClass mc = new MyClass();
System.out.println(mc.num);
However, since you also added the static declaration, you should only access it via the class name, i.e MyClass.num
Point to take home: public variables can exist in any type of class, and they allow you to access them without the need for getters and setters. Public classes, however, are not the only classes that can own public variables.

Is there any reason for public methods in a package protected class?

I wonder if it makes any difference if a method is public or package protected in a class that is package protected.
class Example {
public void test() {}
}
instead of
class Example {
void test() {}
}
I guess the maximum visibility is given by the class. And a method can only reduce the visibility and increasing the visibility has no effect.
But it's valid syntax, so perhaps I've overseen something?
If we subclass Example to a public class , then code outside the package can access test() method using the subclass instance if it is public .
Example:
package A;
class Example {
public void test() {}
}
package A;
public class SubExample extends Example {
}
package B;
import A.SubExample;
class OutsidePackage {
public void some method(SubExample e){
// Had test been defined with default access in class Example
// the below line would be a compilation error.
e.test();
}
}
If Example implemented an interface of some kind you'd have to make them public, because you can't reduce access in that case. All interface methods are, by default, public.
As written, it does nothing. If it's a subclass or interface implementation, then it may be implementing or overriding methods that are declared public elsewhere.

Why we can't create protected methods in JAVA interfaces? [duplicate]

I know that an interface must be public. However, I don't want that.
I want my implemented methods to only be accessible from their own package, so I want my implemented methods to be protected.
The problem is I can't make the interface or the implemented methods protected.
What is a work around? Is there a design pattern that pertains to this problem?
From the Java guide, an abstract class wouldn't do the job either.
read this.
"The public access specifier indicates that the interface can be used by any class in any package. If you do not specify that the interface is public, your interface will be accessible only to classes defined in the same package as the interface."
Is that what you want?
You class can use package protection and still implement an interface:
class Foo implements Runnable
{
public void run()
{
}
}
If you want some methods to be protected / package and others not, it sounds like your classes have more than one responsibility, and should be split into multiple.
Edit after reading comments to this and other responses:
If your are somehow thinking that the visibility of a method affects the ability to invoke that method, think again. Without going to extremes, you cannot prevent someone from using reflection to identify your class' methods and invoke them. However, this is a non-issue: unless someone is trying to crack your code, they're not going to invoke random methods.
Instead, think of private / protected methods as defining a contract for subclasses, and use interfaces to define the contract with the outside world.
Oh, and to the person who decided my example should use K&R bracing: if it's specified in the Terms of Service, sure. Otherwise, can't you find anything better to do with your time?
When I have butted up against this I use a package accessible inner or nested class to implement the interface, pushing the implemented method out of the public class.
Usually it's because I have a class with a specific public API which must implement something else to get it's job done (quite often because the something else was a callback disguised as an interface <grin>) - this happens a lot with things like Comparable. I don't want the public API polluted with the (forced public) interface implementation.
Hope this helps.
Also, if you truly want the methods accessed only by the package, you don't want the protected scope specifier, you want the default (omitted) scope specifier. Using protected will, of course, allow subclasses to see the methods.
BTW, I think that the reason interface methods are inferred to be public is because it is very much the exception to have an interface which is only implemented by classes in the same package; they are very much most often invoked by something in another package, which means they need to be public.
This question is based on a wrong statement:
I know that an interface must be public
Not really, you can have interfaces with default access modifier.
The problem is I can't make the interface or the implemented methods protected
Here it is:
C:\oreyes\cosas\java\interfaces>type a\*.java
a\Inter.java
package a;
interface Inter {
public void face();
}
a\Face.java
package a;
class Face implements Inter {
public void face() {
System.out.println( "face" );
}
}
C:\oreyes\cosas\java\interfaces>type b\*.java
b\Test.java
package b;
import a.Inter;
import a.Face;
public class Test {
public static void main( String [] args ) {
Inter inter = new Face();
inter.face();
}
}
C:\oreyes\cosas\java\interfaces>javac -d . a\*.java b\Test.java
b\Test.java:2: a.Inter is not public in a; cannot be accessed from outside package
import a.Inter;
^
b\Test.java:3: a.Face is not public in a; cannot be accessed from outside package
import a.Face;
^
b\Test.java:7: cannot find symbol
symbol : class Inter
location: class b.Test
Inter inter = new Face();
^
b\Test.java:7: cannot find symbol
symbol : class Face
location: class b.Test
Inter inter = new Face();
^
4 errors
C:\oreyes\cosas\java\interfaces>
Hence, achieving what you wanted, prevent interface and class usage outside of the package.
Here's how it could be done using abstract classes.
The only inconvenient is that it makes you "subclass".
As per the java guide, you should follow that advice "most" of the times, but I think in this situation it will be ok.
public abstract class Ab {
protected abstract void method();
abstract void otherMethod();
public static void main( String [] args ) {
Ab a = new AbImpl();
a.method();
a.otherMethod();
}
}
class AbImpl extends Ab {
protected void method(){
System.out.println( "method invoked from: " + this.getClass().getName() );
}
void otherMethod(){
System.out.println("This time \"default\" access from: " + this.getClass().getName() );
}
}
Here's another solution, inspired by the C++ Pimpl idiom.
If you want to implement an interface, but don't want that implementation to be public, you can create a composed object of an anonymous inner class that implements the interface.
Here's an example. Let's say you have this interface:
public interface Iface {
public void doSomething();
}
You create an object of the Iface type, and put your implementation in there:
public class IfaceUser {
private int someValue;
// Here's our implementor
private Iface impl = new Iface() {
public void doSomething() {
someValue++;
}
};
}
Whenever you need to invoke doSomething(), you invoke it on your composed impl object.
I just came across this trying to build a protected method with the intention of it only being used in a test case. I wanted to delete test data that I had stuffed into a DB table. In any case I was inspired by #Karl Giesing's post. Unfortunately it did not work. I did figure a way to make it work using a protected inner class.
The interface:
package foo;
interface SomeProtectedFoo {
int doSomeFoo();
}
Then the inner class defined as protected in public class:
package foo;
public class MyFoo implements SomePublicFoo {
// public stuff
protected class ProtectedFoo implements SomeProtectedFoo {
public int doSomeFoo() { ... }
}
protected ProtectedFoo pFoo;
protected ProtectedFoo gimmeFoo() {
return new ProtectedFoo();
}
}
You can then access the protected method only from other classes in the same package, as my test code was as show:
package foo;
public class FooTest {
MyFoo myFoo = new MyFoo();
void doProtectedFoo() {
myFoo.pFoo = myFoo.gimmeFoo();
myFoo.pFoo.doSomeFoo();
}
}
A little late for the original poster, but hey, I just found it. :D
You can go with encapsulation instead of inheritance.
That is, create your class (which won't inherit anything) and in it, have an instance of the object you want to extend.
Then you can expose only what you want.
The obvious disadvantage of this is that you must explicitly pass-through methods for everything you want exposed. And it won't be a subclass...
I would just create an abstract class. There is no harm in it.
With an interface you want to define methods that can be exposed by a variety of implementing classes.
Having an interface with protected methods just wouldn't serve that purpose.
I am guessing your problem can be solved by redesigning your class hierarchy.
One way to get around this is (depending on the situation) to just make an anonymous inner class that implements the interface that has protected or private scope. For example:
public class Foo {
interface Callback {
void hiddenMethod();
}
public Foo(Callback callback) {
}
}
Then in the user of Foo:
public class Bar {
private Foo.Callback callback = new Foo.Callback() {
#Override public void hiddenMethod() { ... }
};
private Foo foo = new Foo(callback);
}
This saves you from having the following:
public class Bar implements Foo.Callback {
private Foo foo = new Foo(this);
// uh-oh! the method is public!
#Override public void hiddenMethod() { ... }
}
I think u can use it now with Java 9 release. From the openJdk notes for Java 9,
Support for private methods in interfaces was briefly in consideration
for inclusion in Java SE 8 as part of the effort to add support for
Lambda Expressions, but was withdrawn to enable better focus on higher
priority tasks for Java SE 8. It is now proposed that support for
private interface methods be undertaken thereby enabling non abstract
methods of an interface to share code between them.
refer https://bugs.openjdk.java.net/browse/JDK-8071453

Why doesn't the class containing main have to be public?

I declared the following class
class A { //not public
public static void main(String args[]) {
System.out.println("done");
}
When I compile and run it, it runs fine and prints the output "done". Same behavior even when I declare it as being in a "package a;"
However, if JVM spec mandates that main method should be public since "it can't see main otherwise", shouldn't it apply to the class as well?
If the JVM "can't see" A.main() when it is not declared public, how is it able to see the class A itself.
Is there any explanation for this other than "because the specification says so"?
The JVM has access to every class in the application all the time because one of its responsibilities is enforcing visibility rules. Therefore, one can draw the conclusion that it can ignore visibility rules if need be (e.g. when the user starts the application, the JVM has to find the entry point, which is main()).
In other words, the JVM is not a class accessing this function, so visibility doesn't apply. It is basically the overseer, managing the application from execution to termination.
For reference, see Execution.
When you declare a class private, you're not making it "invisible", and the same goes for your methods. Declaring a method private simply means it's not callable from outside your class. A static public method of a private class is publicly callable.
The reason the JVM can see a non-public class is because it controls visibility, meaning it sees everything and decides what can see/call/access what.
The use of public on a class is different than on a method, but the concept is the same.
On a method, the public keyword means the method can be used outside the class. An example would be:
class A {
public static void do() {
// Do something
}
}
class B {
public static void main(String[] args) {
A.do(); // This works because do() is public and static
}
}
The same concept applies to classes, but in a different way.
Using public on a class means that it can be used outside the current .java file (it will have its own .class file).
Here's an example:
//C.java
class C {
static void do() {
// Do something
}
public static void run() {
A.do(); // Works because A.do() is public and static
B.do(); // Does not work because B is not a public class
}
}
//A.java
public class A {
public static void main(String[] args) {
B.do(); // Works because B is in the same file
do(); // Duh...
}
public static void do() {
// Do something
}
}
class B {
static void do() {
// Do something
}
}

Categories

Resources