小编ass*_*ias的帖子

私有实例成员从匿名静态实例访问

请考虑以下代码:

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)

java enums static private

17
推荐指数
1
解决办法
582
查看次数

AtomicInteger实现和代码重复

警告:问题有点长,但分离线下方的部分仅用于好奇.

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 …

java performance jvm

17
推荐指数
2
解决办法
3629
查看次数

for循环中的最终计数器?

我有这个代码:

    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,问题实际上是关于匿名类,这可能是其他任何东西.

java

16
推荐指数
1
解决办法
3048
查看次数

带有按钮的Android通知

我正在尝试用2个按钮发出通知:

  • 一个人带我回到活动
  • 另一个关闭它

有没有人知道如何捕捉按钮点击事件(请记住活动暂停)?

android android-notifications

16
推荐指数
3
解决办法
4万
查看次数

URLClassLoader和package-private方法的可访问性

我有一个类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 classpath classloader package

16
推荐指数
2
解决办法
2155
查看次数

Java 8 - 区域设置查找行为

在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.

有人可以解释这种行为背后的理由吗?

java locale java-8

16
推荐指数
1
解决办法
2611
查看次数

在opencv-java中优化GrabCut的性能

最近我得到了一个项目,我必须从给定的图像中提取面部(面部+头发).

我通过以下方式解决这个问题.

  1. 我从给定的图像中提取面部位置.[我得到一个矩形]
  2. 我正在提取该矩形并将其放置在与输入图像相同尺寸的另一个图像中.[face_image]
  3. 我在第2步的face_image上应用了grabCut算法.

当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)

java algorithm opencv

16
推荐指数
1
解决办法
3482
查看次数

在switch语句中使用java string.contains

如何将以下代码转换为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)

java switch-statement

15
推荐指数
3
解决办法
4万
查看次数

性能说明:使用未使用的变量,代码运行得更

我之前做过一些性能测试,无法解释我获得的结果.

在运行下面的测试时,如果我取消注释private final List<String> list = new ArrayList<String>();,性能会显着提高.在我的机器上,测试在该字段存在时以70-90毫秒运行,而在注释掉时则为650毫秒.

我还注意到,如果我将print语句更改为System.out.println((end - start) / 1000000);,则没有变量的测试运行时间为450-500 ms而不是650 ms.变量存在时无效.

我的问题:

  1. 考虑到我甚至不使用那个变量,任何人都可以解释有或没有变量的近10个因子吗?
  2. 该打印语句如何改变性能(特别是性能测量窗口之后)?

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)

java performance multithreading jvm

15
推荐指数
1
解决办法
946
查看次数

HashMap和可见性

HashMap的javadoc声明:

如果在创建迭代器之后的任何时候对映射进行结构修改,除了通过迭代器自己的remove方法之外,迭代器将抛出ConcurrentModificationException.

我构建了一个示例代码,根据规范,它应该几乎立即失败并抛出ConcurrentModificationException;

  • 它会像Java 7那样立即失败
  • 但它(似乎)始终使用Java 6(即它不会抛出承诺的异常).

注意:它有时不会因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)

java multithreading hashmap

14
推荐指数
2
解决办法
1329
查看次数