我对一些文档使用的术语"包私有"以及"默认访问"的使用感到有些困惑.包私有和默认访问都不是protected的同义词吗?
我最近在学习Java,我遇到了package-private类的概念,如果我们没有指定任何东西,这是默认的.但后来我意识到:
我很少看到使用package-private类.是否有这样的原因,例如,它有严重的缺点,它是多余的,或者只是我阅读不够?是否有强烈的论据支持/反对其使用?
如果它在大多数情况下确实没用,为什么它会是默认值?
在什么情况下我们应该在现实世界中使用package-private?即,什么时候会变得不可替代?
换句话说,默认的package-private修饰符的主要优点和缺点是什么?
我试图使用反射获得一个不可见类,AKA包私有类的实例.我想知道是否有办法切换修饰符使其公开然后使用它来访问它Class.forName.当我尝试这一点时,它阻止我说我不能这样做.不幸的是setAccesible,Class班上没有方法.
在一个包(a)中,我有两个功能接口:
package a;
@FunctionalInterface
interface Applicable<A extends Applicable<A>> {
void apply(A self);
}
Run Code Online (Sandbox Code Playgroud)
-
package a;
@FunctionalInterface
public interface SomeApplicable extends Applicable<SomeApplicable> {
}
Run Code Online (Sandbox Code Playgroud)
apply超级接口中的方法采用selfas,A否则,如果Applicable<A>使用if ,则类型在包外不可见,因此无法实现该方法.
在另一个包(b)中,我有以下Test类:
package b;
import a.SomeApplicable;
public class Test {
public static void main(String[] args) {
// implement using an anonymous class
SomeApplicable a = new SomeApplicable() {
@Override
public void apply(SomeApplicable self) {
System.out.println("a");
}
};
a.apply(a);
// implement using a …Run Code Online (Sandbox Code Playgroud) 如果测试所在的模块与生产代码不同(这是常见的),那么使内部函数对测试可见的最佳方法是什么?
在Java中,我将生产代码和测试放在同一个包中,并使待测试的方法包私有(另外,@VisibleForTest如果将包装私有而非私有的唯一原因是添加注释)测试).不幸的是,Kotlin没有包私有的概念.
我正在寻找以下行为的解释:
这些是类:
package a;
public class A {
void m() { System.out.println("A"); }
}
// ------
package b;
import a.A;
public class B extends A {
void m() { System.out.println("B"); }
}
// ------
package c;
import b.B;
public class C extends B {
void m() { System.out.println("C"); }
}
// ------
package a;
import c.C;
public class D extends C {
void m() { System.out.println("D"); }
}
// ------
package b;
import a.D;
public class E …Run Code Online (Sandbox Code Playgroud) 假设我的包中有一个类,org.jake它有一个默认访问的方法(没有修饰符).然后该方法仅在包内可见.
然而,当有人收到我的框架的jar时,是什么阻止他们编写一个新的类,声明它的包org.jake,并使用我所谓的隐形方法?
换句话说,有什么办法可以防止这种情况发生吗?
我刚刚从Java代码中使用Scala代码生成的字节码时,我发现Scala范围很奇怪.请考虑使用Spark(Spark 1.4,Hadoop 2.6)的以下代码段:
import java.util.Arrays;
import java.util.List;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.broadcast.Broadcast;
public class Test {
public static void main(String[] args) {
JavaSparkContext sc =
new JavaSparkContext(new SparkConf()
.setMaster("local[*]")
.setAppName("test"));
Broadcast<List<Integer>> broadcast = sc.broadcast(Arrays.asList(1, 2, 3));
broadcast.destroy(true);
// fails with java.io.IOException: org.apache.spark.SparkException:
// Attempted to use Broadcast(0) after it was destroyed
sc.parallelize(Arrays.asList("task1", "task2"), 2)
.foreach(x -> System.out.println(broadcast.getValue()));
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码失败了,这是因为我Broadcast在使用它之前自愿销毁它,但问题是在我的心理模型中它甚至不应该编译,更不用说运行正常了.
事实上,Broadcast.destroy(Boolean)声明是private[spark]这样,它不应该从我的代码可见.我会尝试查看字节码,Broadcast但这不是我的专长,这就是我更喜欢发布这个问题的原因.另外,抱歉,我太懒了,不能创建一个不依赖Spark的例子,但至少你明白了.请注意,我可以使用Spark的各种package-private方法,它不仅仅是Broadcast.
知道发生了什么事吗?
我正在学习C#并来自Java世界,我有点困惑,看到C#没有"包私有".我见过的关于这一点的大多数评论都是"你不能这样做;语言不是这样设计的".我还看到了一些涉及的工作区internal,partial以及评论说这些变通方法违背了语言的设计.
为什么C#这样设计?另外,我将如何做以下事情:我有一个Product班级和一个ProductInstance班级.我想要ProductInstance创建的唯一方法是通过类中的工厂方法Product.在Java中,我会放入ProductInstance相同的包Product,但是使它的构造函数package private只能Product访问它.这样,任何想要创建的人ProductInstance都只能通过类中的工厂方法来创建Product.我如何在C#中完成同样的事情?
package-private ×10
java ×9
class ×2
apache-spark ×1
bytecode ×1
c# ×1
default ×1
enums ×1
generics ×1
inheritance ×1
kotlin ×1
lambda ×1
modifier ×1
overriding ×1
protected ×1
reflection ×1
scala ×1
shadowing ×1
terminology ×1
unit-testing ×1