I have a private inner class implementing a private inner interface. I usually omit the private modifier inside private inner classes to make the code cleaner. Unfortunately, in this situation I get "can't reduce visibility error", even though I'm not actually reducing visibility.
public class Foo {
private interface IBar{
void foo();
}
private static class Bar implements IBar{
#Override
public void foo() { // Must be public :(
}
}
}
I presume there is no way to work around this?
All methods of an interface are public and abstract. That is the rule.
Only making them public makes sense because they are to be implemented by implementing classes which may be from different packages.
and even if it is an inner interface, it still is interface So rules do not change.
All methods on an interface must be declared public. Not specifying an access modifier on the foo method causes it to be assigned package protected access by default. Since package protected is less accessible than public the code is reducing the accessibility of the foo method.
All methods of an inteface are public and abstract. If you don't define any modifier then by default it is public and abstract.
The general rule of override is you can't reduce the method visibility. In side a class if you don't define any modifier then by default it will be default and default is less visible then public. So here it must be public
Related
My Question is about interface. I create an interface and define four methods: first method is a private method; second is a default method; third is a static method; and fourth is an abstract method.
After compiling this interface and checking its profile: the default method is converted into a public method, and both the static and abstract methods have a prepended public modifier. Why is this?
Code:
interface InterfaceProfile {
private void privateM() { //this method is hidden
System.out.println("private Method");
}
default void defaultM() {
System.out.println("Default Method");
}
static void staticM() {
System.out.println("Static Method");
}
void doStuff(); //by default adds the public modifier
}
InterfaceProfile class
D:\Linux\IDE\Workspace\OCA-Wrokspace\Ocaexam\src>javap mods\com\doubt\session\InterfaceProfile.class
Compiled from "InterfaceProfile.java"
interface com.doubt.session.InterfaceProfile {
public void defaultM();
public static void staticM();
public abstract void doStuff();
}
The fact that it's a default method doesn't make a difference. The implicit scope is public.
Here's what the tutorial says:
All abstract, default, and static methods in an interface are implicitly public, so you can omit the public modifier.
Simple: by default, all methods in an interface are public. You can restrict that by applying private, but whenever you do not do that, that default kicks in. Thus: there is no conversion taking place at all.
Quoting the Java Language Specification:
A method in the body of an interface may be declared public or private (ยง6.6). If no access modifier is given, the method is implicitly public. It is permitted, but discouraged as a matter of style, to redundantly specify the public modifier for a method declaration in an interface.
( the ability to have private methods in interfaces was introduced with Java 9, as people discovered that Java 8 default methods often created the need to have, well, private methods that such default methods could make use of, without making these helper methods publicly visible )
The default modifier is public, because that is how the interface declaration is defined:
https://docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
If you are asking for the reasoning behind this, i would argue that the purpose of defining an interface is to ensure the - well - interface of all implementing classes, meaning that all implementing classes have clear contracts on which public accessable methods they need to provide.
Adding private methods to an interface does not serve this primary purpose and seems to be more of an implementation hint. Private and abstract methods were late additions to interfaces.
Related: Should methods in a Java interface be declared with or without a public access modifier?
https://docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
All abstract, default, and static methods in an interface are implicitly public, so you can omit the public modifier.
In effect, a class that implements an interface exposes all of the interface methods (other than private) to any other code that has visibility of the class.
It would be very confusing if a class had an interface but the methods on the interface would be visible to some code and not other. If you want to selectively expose methods, then you should probably make use of multiple interfaces.
public interface Profile {
generalMethod() ...
}
public interface SecretProfile extends Profile {
secretMethod() ...
}
Classes may choose to implement either of the interfaces (or even both). 3rd party code can check for the presence of the interface and know that the method is available or not.
Recently, I was writing a class that I decided to be package-private (that is, no access modifier, or the default one). It has an inner class and some private helper methods, and one method intended to be used by a class in the same package. All of these class members are static. But then I had a thought: should this one method have the public access modifier or no access modifier, like the class containing it?
On one hand, since the class itself is package-private, it can only be accessed and used within its package, so there is no practical reason to make the method public. But at the same time, semantically, this method is intended to be a public feature of the class, that is, a feature of the class intended to be used externally, so it would make sense to modify its access as such.
For those that like to see code,
final class DummyRemover {
private DummyRemover() {
}
public static int remove(Map<String, ClassNode> classMap) {
return 0;
}
// ...
}
or,
final class DummyRemover {
private DummyRemover() {
}
// Notice the modifier.
static int remove(Map<String, ClassNode> classMap) {
return 0;
}
// ...
}
What is the best choice here? Is there a rule of thumb for deciding what access modifiers to use in a case like this?
There are two reasons why a method should have a higher visibility than its enclosing class:
1. The enclosing class is a base class
... which is intended for extension by subclasses, which might eventually be public, and the method at hand is supposed to be publicly available. E.g.
abstract class Base {
public void x() {}
}
public class Sub extends Base {
}
// Now, everyone can call:
new Sub().x();
usually, however, if this is your intention, you will declare your method x() in an interface anyway. Even if you don't declare x() in an interface, design-wise, it's probably better to keep the base method at the same visibility level as its class, and "open up" the method in the subclass, as that will communicate intent more clearly:
abstract class Base {
void x() {}
}
public class Sub extends Base {
/** public Javadoc here */
#Override
public void x() {
super.x();
}
}
I don't see any reason why this approach should be applied to static methods as in your case.
2. The method must be public
... because it implements a method from an interface. Unfortunately, Java doesn't offer package-private or private interface methods. So the following is usual, even without any subclasses, and even if the interface itself might be package-private (or even nested private):
final class Y implements X {
#Override
public void x() {}
}
This (unfortunately) also applies to static classes on interfaces, which can only be public:
interface I {
/* implicitly public */ static void x() {}
}
There are two schools of thought on this:
One group prefers adding unnecessary modifiers (e.g. public in this case, private in private classes) as a form of "documentation in code". For example, this is the viewpoint Eric Lippert espouses in his answer on this related C# question.
The other group prefers to never add source code that has no functional effect: if public isn't doing anything then it doesn't belong in your source code.
I think I am now firmly in the second camp, but I understand the arguments from the first camp and I think it's not nearly as cut and dried as it might first appear. Reasonable people can disagree, which is why (like braces and whitespace) this is something you should decide once in a project style guide and then never debate again. :-)
I personally think that making the method public might be misleading to the reader.
On the other hand, it supports extensibility (If the class should ever be made public, the change is easier).
Whenever I need to choose between readability and extensibility, I go for the YAGNI principle and choose readability.
See wiki for more about YAGNI: https://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it
I wonder if it's okay (not considered bad practice) to have public members in package private class. I tend to add public keyword to members of my default visibility classes to indicate that such members are part of the classes API.
I do it only for readability, since in this case public members have essentially the same visibility as members without any access modifiers (i.e. package visibility). Is that correct?
Example:
class ModuleImplementationClass {
private int fieldA;
private String fieldB;
private void someClassInternalMethod() {
// impl
}
public int doSth() {
// method that will be called by other classes in the package
}
}
I do it only for readability, since in this case public members have essentially the same visibility as members without any access modifiers (i.e. package visibility). Is that correct?
Well that depends. Not if you're overriding existing methods (e.g. toString()) or implementing an interface.
If you don't want the method to be used from outside the package, make it package private. If you're happy for it to be used from anywhere, make it public. Or another way to think about it: design your method access so that if someone changed just the class access to make it a public class, you wouldn't want to change the method access too.
I have the following situation.
package A;
class SampleClass
{
static interface sampleInterface
{
....
}
}
Now when I try to import the sampleInterface from another package , jDev says 'access not allowed'. What could be the problem?
Currently, the interface is seen as package-private (there's no visibility modifier, so that's the default). Place public on the outer class and the interface, and it will become visible to other classes.
Just be careful - if you get caught in a situation where you have to do this:
public class Alpha extends Alpha.IAlpha {
public void doNothing();
public static interface IAlpha {
public void doNothing();
}
}
...you'll have an issue with cyclic inheritance, and your class won't compile. In fact, you won't be able to use the interface at all.
Keep these rules in mind for exposing interfaces, classes, or enums:
If you only need an inner class, interface, or enum for that particular object, then it's fine to declare it as static.
If you need a class, interface, or enum accessible from anywhere but that object, then it's best to move it out of the inner class, and into its own file.
In general, interfaces are seen as APIs to conform by - there's really no benefit in having them as nested unless the scope of them is extremely narrow.
Change visibility of the class and the interface to public. It will work for sure.
When you declare a class without a access specifier it is by package-default. This means you can access that class in that package only.
If you want to access class from another package, make class public, i.e.
public class SampleClass
Similarly, in your case, as you want to access the Interface as well, you have to make that interface public as well.
This will solve your problem.
I have a class that offers a collection of static utility-type methods.
On the one hand, I don't want the class to be able to be instantiated. On the other hand, I don't want to send the signal that the class should be inherited from (not that I think that it's likely).
Should this class be abstract or not?
make the class final and make the default constructor private and do not provide any public constructors. that way no one can subclass it or create an instance of it.
Don't declare it abstract; declare a private constructor, so no one, not even a subclass, can instantiate an instance of your utility class.
You can declare your class final, although if all constructors are private, then no one will be able to subclass it anyway.
To borrow the idea from Pshemo's comment in another answer, throw a RuntimeException in the constructor to prevent reflection's setAccessible method in AccessibleObject from allowing instantiation:
public class MyUtility
{
private MyUtility()
{
throw new RuntimeException("Instantiation of MyUtility is not allowed!");
}
public static void utilityMethod()
{
// Your utility method here.
}
}
Although a top-level class can't be declared static, you can make the class non-instantiable (and practically 'static') to other classes by declaring the default constructor private, which forbids instantiation because no constructor is visible.
Another version of #mre's answer
enum MyClass{
;//this semicolon indicates that this enum will have no instances
//now you can put your methods
public static void myMethod(){
//...
}
}
Enum by default is final and its constructor is private. Also you cant create its instance with reflection because it checks in Constructor#newInstance if you are trying to instantiate Enum object.
What is contained in a class has no bearing on whether it should be abstract. The key take away: an abstract class must have another class extending it (a 'concrete' class); only that concrete class can be instantiated.
To prevent it from being extended, use final.
To prevent it from being instantiated, make the constructor private.
Observe that in Java these are discrete concepts.
No, it is a utility class.
It should be final with a private default constuctor, to avoid instantiation.
If you have checkstyle enabled you would get a warning if you dont do it.
Seriously, you don't have to do anything. Nothing bad will happen, nobody is going to instantiate/subclass your class.
In addition to all the other calls to give the class a private constructor, you should also make it final so that it is clear nothing can subclass it.
public final class Utils
{
// prevent accidental construction.
private Utils()
{
}
public static void foo()
{
//util code here
}
}