请考虑以下代码:
enum E {
A { public int get() { return i; } },
B { public int get() { return this.i; } },
C { public int get() { return super.i; } },
D { public int get() { return D.i; } };
private int i = 0;
E() { this.i = 1; }
public abstract int get();
}
Run Code Online (Sandbox Code Playgroud)
我在前2个枚举常量声明(A和B)上得到编译时错误,但最后2个编译正常(C&D).错误是:
A行的错误1:非静态变量i无法从静态上下文引用
B行上的错误2:我在E中有私有访问权限
由于get是一个实例方法,我不明白为什么我不能i以我想要的方式访问实例变量.
注意:private从声明中删除关键字i也会使代码可编辑,我也不明白.
使用Oracle JDK 7u9.
编辑
正如评论中所指出的,这不是枚举特有的,下面的代码会产生相同的行为:
class E …Run Code Online (Sandbox Code Playgroud) 警告:问题有点长,但分离线下方的部分仅用于好奇.
Oracle的AtomicInteger的JDK 7实现包括以下方法:
public final int addAndGet(int delta) {
for (;;) {
int current = get();
int next = current + delta; // Only difference
if (compareAndSet(current, next))
return next;
}
}
public final int incrementAndGet() {
for (;;) {
int current = get();
int next = current + 1; // Only difference
if (compareAndSet(current, next))
return next;
}
}
Run Code Online (Sandbox Code Playgroud)
很明显第二种方法可以写成:
public final int incrementAndGet() {
return addAndGet(1);
}
Run Code Online (Sandbox Code Playgroud)
在该类中还有其他几个类似代码重复的例子.我想不出有任何理由这样做,而是考虑性能(*).我很确定作者在确定设计之前做了一些深入的测试.
为什么(或在什么情况下)第一个代码比第二个代码表现更好?
(*)我无法抗拒,但写了一个快速的微基准.它显示(后JIT)系统性差距为2-4%,有利于addAndGet(1)vs incrementAndGet()(虽然很小,但它非常一致).说实话,我无法真正解释这个结果......
输出:
incrementAndGet():905 …
我有这个代码:
List<Runnable> r = new ArrayList<>();
for(int i = 0; i < 10; i++) {
r.add(new Runnable() {
@Override
public void run() {
System.out.println(i);
}
});
}
Run Code Online (Sandbox Code Playgroud)
它显然无法编译,因为i需要最终才能在匿名类中使用.但我不能把它作为最终决定,因为事实并非如此.你会怎么做?一个解决方案是复制它,但我认为可能有更好的方法:
List<Runnable> r = new ArrayList<>();
for(int i = 0; i < 10; i++) {
final int i_final = i;
r.add(new Runnable() {
@Override
public void run() {
System.out.println(i_final);
}
});
}
Run Code Online (Sandbox Code Playgroud)
编辑只是为了说清楚,我为了这个例子在这里使用了Runnable,问题实际上是关于匿名类,这可能是其他任何东西.
我正在尝试用2个按钮发出通知:
有没有人知道如何捕捉按钮点击事件(请记住活动暂停)?
我有一个类Formula,位于包中javaapplication4,我使用URLClassLoader加载.但是,当我从Test1位于同一个包中的另一个类调用它时,我无法访问其具有默认访问修饰符的方法(我可以访问公共方法).
我得到以下异常:
java.lang.IllegalAccessException:类javaapplication4.Test1无法使用修饰符""访问类javaapplication4.Formula的成员
如何从同一个包中访问在运行时加载的类的包私有方法?
我想使用不同的类加载器是一个问题,但不确定为什么(我已经设置了URLClassLoader的父级).
SSCCE再现问题(Windows路径) - 我想问题出在loadClass方法中:
public class Test1 {
private static final Path TEMP_PATH = Paths.get("C:/temp/");
public static void main(String[] args) throws Exception {
String thisPackage = Test1.class.getPackage().getName();
String className = thisPackage + ".Formula"; //javaapplication4.Formula
String body = "package " + thisPackage + "; "
+ "public class Formula { "
+ " double calculateFails() { "
+ " return 123; "
+ " } "
+ " public …Run Code Online (Sandbox Code Playgroud) 在Java 8中引入Locale.lookup(),基于RFC 4647,允许用户Locale根据优先级列表找到最佳匹配列表LocaleRange.现在我不明白这种方法的每个角落情况.以下公开了一个我想要解释的具体案例:
// Create a collection of Locale objects to search
Collection<Locale> locales = new ArrayList<>();
locales.add(Locale.forLanguageTag("en-GB"));
locales.add(Locale.forLanguageTag("en"));
// Express the user's preferences with a Language Priority List
String ranges = "en-US;q=1.0,en-GB;q=1.0";
List<Locale.LanguageRange> languageRanges = Locale.LanguageRange.parse(ranges);
// Find the BEST match, and return just one result
Locale result = Locale.lookup(languageRanges,locales);
System.out.println(result.toString());
Run Code Online (Sandbox Code Playgroud)
这打印en,我会直观地预期en-GB.
注意:
"en-GB;q=1.0,en-US;q=1.0"(GB和US反转),这将打印en-GB,"en-US;q=0.9,en-GB;q=1.0"(GB的优先级高于美国),这将打印出来en-GB.有人可以解释这种行为背后的理由吗?
最近我得到了一个项目,我必须从给定的图像中提取面部(面部+头发).
我通过以下方式解决这个问题.
当face_image包含平滑背景时,算法会抓住它,但是当face_image的背景很复杂时,算法grabCut也会在处理过的图像中提取背景的某些部分.
这是我得到的结果的快照.

这是我的grabCut代码:
public void extractFace(Mat image, String fileNameWithCompletePath,
int xOne, int xTwo, int yOne, int yTwo) throws CvException {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
Rect rectangle = new Rect(xOne, yOne, xTwo, yTwo);
Mat result = new Mat();
Mat bgdModel = new Mat();
Mat fgdModel = new Mat();
Mat source = new Mat(1, 1, CvType.CV_8U, new Scalar(3));
Imgproc.grabCut(image, result, rectangle, bgdModel, fgdModel, 8, Imgproc.GC_INIT_WITH_RECT);
Core.compare(result, source, result, Core.CMP_EQ);
Mat foreground = …Run Code Online (Sandbox Code Playgroud) 如何将以下代码转换为switch语句?
String x = "user input";
if (x.contains("A")) {
//condition A;
} else if (x.contains("B")) {
//condition B;
} else if(x.contains("C")) {
//condition C;
} else {
//condition D;
}
Run Code Online (Sandbox Code Playgroud) 我之前做过一些性能测试,无法解释我获得的结果.
在运行下面的测试时,如果我取消注释private final List<String> list = new ArrayList<String>();,性能会显着提高.在我的机器上,测试在该字段存在时以70-90毫秒运行,而在注释掉时则为650毫秒.
我还注意到,如果我将print语句更改为System.out.println((end - start) / 1000000);,则没有变量的测试运行时间为450-500 ms而不是650 ms.变量存在时无效.
我的问题:
ps:当顺序运行时,3个场景(带有变量,没有变量,带有不同的print语句)都需要大约260ms.
public class SOTest {
private static final int ITERATIONS = 10000000;
private static final int THREADS = 4;
private volatile long id = 0L;
//private final List<String> list = new ArrayList<String>();
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(THREADS);
final List<SOTest> objects = new ArrayList<SOTest>();
for (int i = 0; i …Run Code Online (Sandbox Code Playgroud) 如果在创建迭代器之后的任何时候对映射进行结构修改,除了通过迭代器自己的remove方法之外,迭代器将抛出ConcurrentModificationException.
我构建了一个示例代码,根据规范,它应该几乎立即失败并抛出ConcurrentModificationException;
注意:它有时不会因Java 7而失败(比如20次中的1次) - 我猜它与线程调度有关(即2个runnables不是交错的).
我错过了什么吗?为什么使用Java 6运行的版本不会抛出ConcurrentModificationException?
实质上,有2个Runnable任务并行运行(倒计时器用于使它们大约同时启动):
然后主线程检查已添加到阵列的键数.
Java 7典型输出(迭代立即失败):
java.util.ConcurrentModificationException
MAX i = 0
Java 6典型输出(整个迭代通过,数组包含所有添加的键):
MAX i = 99
使用的代码:
public class Test1 {
public static void main(String[] args) throws InterruptedException {
final int SIZE = 100;
final Map<Integer, Integer> map = new HashMap<Integer, Integer>();
map.put(1, 1);
map.put(2, 2);
map.put(3, 3);
final int[] list = new int[SIZE];
final CountDownLatch start = new CountDownLatch(1);
Runnable put …Run Code Online (Sandbox Code Playgroud)