问题描述
我知道Java中的类仅使用“公共”和“默认(无修饰符)”,并且当您尝试将一个类声明为“私有”或“受保护”时,它会给出编译错误,这很有意义给我。
但是,然后this page为什么说“类可以具有上述4个中的任何修饰符”。
有人可以向我解释一下吗?
解决方法
就像文字说的那样:
并非所有类都允许使用所有修饰符
但是,例如inner classes可以是私有的/受保护的。
public class Foo {
private Bar bar = new Bar(42);
private static class Bar {
private int answer;
Bar(int theAnswer) {
this.answer = theAnswer;
}
}
}
这对于保存某些POJO数据或要封装但不泄漏的某些内部实现细节是有意义的(如果受到保护,您甚至可以覆盖)。
,还有更多合法组合。只是为了好玩,我写了一个小脚本来生成所有可能的组合,然后删除了导致编译错误的脚本,这些是合法的:
class Test {
class Default__ConcreteInstanceVirtualLoosefp_Class {}
interface Default__ConcreteInstanceVirtualLoosefp_Interface {}
record Default__ConcreteInstanceVirtualLoosefp_Record() {}
strictfp class Default__ConcreteInstanceVirtualStrictfpClass {}
strictfp interface Default__ConcreteInstanceVirtualStrictfpInterface {}
strictfp record Default__ConcreteInstanceVirtualStrictfpRecord() {}
final class Default__ConcreteInstanceFinal__Loosefp_Class {}
final record Default__ConcreteInstanceFinal__Loosefp_Record() {}
final strictfp class Default__ConcreteInstanceFinal__StrictfpClass {}
final strictfp record Default__ConcreteInstanceFinal__StrictfpRecord() {}
static class Default__ConcreteStatic__VirtualLoosefp_Class {}
static interface Default__ConcreteStatic__VirtualLoosefp_Interface {}
static record Default__ConcreteStatic__VirtualLoosefp_Record() {}
static strictfp class Default__ConcreteStatic__VirtualStrictfpClass {}
static strictfp interface Default__ConcreteStatic__VirtualStrictfpInterface {}
static strictfp record Default__ConcreteStatic__VirtualStrictfpRecord() {}
static final class Default__ConcreteStatic__Final__Loosefp_Class {}
static final record Default__ConcreteStatic__Final__Loosefp_Record() {}
static final strictfp class Default__ConcreteStatic__Final__StrictfpClass {}
static final strictfp record Default__ConcreteStatic__Final__StrictfpRecord() {}
abstract class Default__AbstractInstanceVirtualLoosefp_Class {}
abstract interface Default__AbstractInstanceVirtualLoosefp_Interface {}
abstract strictfp class Default__AbstractInstanceVirtualStrictfpClass {}
abstract strictfp interface Default__AbstractInstanceVirtualStrictfpInterface {}
abstract static class Default__AbstractStatic__VirtualLoosefp_Class {}
abstract static interface Default__AbstractStatic__VirtualLoosefp_Interface {}
abstract static strictfp class Default__AbstractStatic__VirtualStrictfpClass {}
abstract static strictfp interface Default__AbstractStatic__VirtualStrictfpInterface {}
public class Public___ConcreteInstanceVirtualLoosefp_Class {}
public interface Public___ConcreteInstanceVirtualLoosefp_Interface {}
public record Public___ConcreteInstanceVirtualLoosefp_Record() {}
public strictfp class Public___ConcreteInstanceVirtualStrictfpClass {}
public strictfp interface Public___ConcreteInstanceVirtualStrictfpInterface {}
public strictfp record Public___ConcreteInstanceVirtualStrictfpRecord() {}
public final class Public___ConcreteInstanceFinal__Loosefp_Class {}
public final record Public___ConcreteInstanceFinal__Loosefp_Record() {}
public final strictfp class Public___ConcreteInstanceFinal__StrictfpClass {}
public final strictfp record Public___ConcreteInstanceFinal__StrictfpRecord() {}
public static class Public___ConcreteStatic__VirtualLoosefp_Class {}
public static interface Public___ConcreteStatic__VirtualLoosefp_Interface {}
public static record Public___ConcreteStatic__VirtualLoosefp_Record() {}
public static strictfp class Public___ConcreteStatic__VirtualStrictfpClass {}
public static strictfp interface Public___ConcreteStatic__VirtualStrictfpInterface {}
public static strictfp record Public___ConcreteStatic__VirtualStrictfpRecord() {}
public static final class Public___ConcreteStatic__Final__Loosefp_Class {}
public static final record Public___ConcreteStatic__Final__Loosefp_Record() {}
public static final strictfp class Public___ConcreteStatic__Final__StrictfpClass {}
public static final strictfp record Public___ConcreteStatic__Final__StrictfpRecord() {}
public abstract class Public___AbstractInstanceVirtualLoosefp_Class {}
public abstract interface Public___AbstractInstanceVirtualLoosefp_Interface {}
public abstract strictfp class Public___AbstractInstanceVirtualStrictfpClass {}
public abstract strictfp interface Public___AbstractInstanceVirtualStrictfpInterface {}
public abstract static class Public___AbstractStatic__VirtualLoosefp_Class {}
public abstract static interface Public___AbstractStatic__VirtualLoosefp_Interface {}
public abstract static strictfp class Public___AbstractStatic__VirtualStrictfpClass {}
public abstract static strictfp interface Public___AbstractStatic__VirtualStrictfpInterface {}
private class Private__ConcreteInstanceVirtualLoosefp_Class {}
private interface Private__ConcreteInstanceVirtualLoosefp_Interface {}
private record Private__ConcreteInstanceVirtualLoosefp_Record() {}
private strictfp class Private__ConcreteInstanceVirtualStrictfpClass {}
private strictfp interface Private__ConcreteInstanceVirtualStrictfpInterface {}
private strictfp record Private__ConcreteInstanceVirtualStrictfpRecord() {}
private final class Private__ConcreteInstanceFinal__Loosefp_Class {}
private final record Private__ConcreteInstanceFinal__Loosefp_Record() {}
private final strictfp class Private__ConcreteInstanceFinal__StrictfpClass {}
private final strictfp record Private__ConcreteInstanceFinal__StrictfpRecord() {}
private static class Private__ConcreteStatic__VirtualLoosefp_Class {}
private static interface Private__ConcreteStatic__VirtualLoosefp_Interface {}
private static record Private__ConcreteStatic__VirtualLoosefp_Record() {}
private static strictfp class Private__ConcreteStatic__VirtualStrictfpClass {}
private static strictfp interface Private__ConcreteStatic__VirtualStrictfpInterface {}
private static strictfp record Private__ConcreteStatic__VirtualStrictfpRecord() {}
private static final class Private__ConcreteStatic__Final__Loosefp_Class {}
private static final record Private__ConcreteStatic__Final__Loosefp_Record() {}
private static final strictfp class Private__ConcreteStatic__Final__StrictfpClass {}
private static final strictfp record Private__ConcreteStatic__Final__StrictfpRecord() {}
private abstract class Private__AbstractInstanceVirtualLoosefp_Class {}
private abstract interface Private__AbstractInstanceVirtualLoosefp_Interface {}
private abstract strictfp class Private__AbstractInstanceVirtualStrictfpClass {}
private abstract strictfp interface Private__AbstractInstanceVirtualStrictfpInterface {}
private abstract static class Private__AbstractStatic__VirtualLoosefp_Class {}
private abstract static interface Private__AbstractStatic__VirtualLoosefp_Interface {}
private abstract static strictfp class Private__AbstractStatic__VirtualStrictfpClass {}
private abstract static strictfp interface Private__AbstractStatic__VirtualStrictfpInterface {}
protected class ProtectedConcreteInstanceVirtualLoosefp_Class {}
protected interface ProtectedConcreteInstanceVirtualLoosefp_Interface {}
protected record ProtectedConcreteInstanceVirtualLoosefp_Record() {}
protected strictfp class ProtectedConcreteInstanceVirtualStrictfpClass {}
protected strictfp interface ProtectedConcreteInstanceVirtualStrictfpInterface {}
protected strictfp record ProtectedConcreteInstanceVirtualStrictfpRecord() {}
protected final class ProtectedConcreteInstanceFinal__Loosefp_Class {}
protected final record ProtectedConcreteInstanceFinal__Loosefp_Record() {}
protected final strictfp class ProtectedConcreteInstanceFinal__StrictfpClass {}
protected final strictfp record ProtectedConcreteInstanceFinal__StrictfpRecord() {}
protected static class ProtectedConcreteStatic__VirtualLoosefp_Class {}
protected static interface ProtectedConcreteStatic__VirtualLoosefp_Interface {}
protected static record ProtectedConcreteStatic__VirtualLoosefp_Record() {}
protected static strictfp class ProtectedConcreteStatic__VirtualStrictfpClass {}
protected static strictfp interface ProtectedConcreteStatic__VirtualStrictfpInterface {}
protected static strictfp record ProtectedConcreteStatic__VirtualStrictfpRecord() {}
protected static final class ProtectedConcreteStatic__Final__Loosefp_Class {}
protected static final record ProtectedConcreteStatic__Final__Loosefp_Record() {}
protected static final strictfp class ProtectedConcreteStatic__Final__StrictfpClass {}
protected static final strictfp record ProtectedConcreteStatic__Final__StrictfpRecord() {}
protected abstract class ProtectedAbstractInstanceVirtualLoosefp_Class {}
protected abstract interface ProtectedAbstractInstanceVirtualLoosefp_Interface {}
protected abstract strictfp class ProtectedAbstractInstanceVirtualStrictfpClass {}
protected abstract strictfp interface ProtectedAbstractInstanceVirtualStrictfpInterface {}
protected abstract static class ProtectedAbstractStatic__VirtualLoosefp_Class {}
protected abstract static interface ProtectedAbstractStatic__VirtualLoosefp_Interface {}
protected abstract static strictfp class ProtectedAbstractStatic__VirtualStrictfpClass {}
protected abstract static strictfp interface ProtectedAbstractStatic__VirtualStrictfpInterface {}
}
因此,如果您包括Java 14实验性record
或单独计算,则总共有112种合法组合,record
的修饰符有32种合法组合,{{1 }},如果仅计算班级,则为48。
最明显的非法组合是:
-
interface
和abstract
:final
的意思是“包含必须由子类实现的未实现成员”,而abstract
的意思是“不能被子类化”,需要子类但不能有子类的类没有道理。 - 出于相同的原因,您不能拥有
final
的{{1}}:interface
是隐式完全final
的,因为它应该由其实现的interface
是。 - 相反,
abstract
是隐式class
,因此它们不能是record
。