小编Kev*_*n K的帖子

在Java中,是否有合理的理由从类构造函数中调用非final方法?

我最近花了几分钟调试生产代码中的问题,最终结果是由在其构造函数中调用抽象方法的类引起的,并且该方法的子类实现尝试使用尚未生成的子类字段已初始化(下面列出了一个说明这一点的例子)

在研究这个问题时,我偶然发现了这个问题,并对Jon Skeet的回答很感兴趣:

一般来说,在构造函数中调用非final方法是一个坏主意,正是因为这个原因 - 子类构造函数体还没有被执行,所以你有效地在一个尚未完全调用的环境中调用一个方法初始化.

这让我感到疑惑,是否有合理的理由从构造函数中调用非final或抽象方法?或者它几乎总是设计糟糕的迹象?

public class SSCCE {
    static abstract class A {
        public A() {
            method();  // Not good; field arr in B will be null at this point!
        }

        abstract void method();
    }

    static class B extends A {
        final String[] arr = new String[] { "foo", "bar" };

        public B() {
            super();
            System.out.println("In B(): " + Arrays.toString(arr));
        }

        void method() {
            System.out.println("In method(): " + Arrays.toString(arr));
        }
    }

    public static void …
Run Code Online (Sandbox Code Playgroud)

java inheritance

12
推荐指数
2
解决办法
2272
查看次数

为什么java/lang/System中的nullPrintStream()函数将currentTimeMillis()与零进行比较?

当装载系统类,该<clinit>方法实例化in,out以及err PrintStream变量null使用nullPrintStream()方法:

private static PrintStream nullPrintStream() throws NullPointerException {
    if (currentTimeMillis() > 0) {
        return null;
    }
    throw new NullPointerException();
}
Run Code Online (Sandbox Code Playgroud)

我明白为什么会这样,以及为什么变量在加载过程中无法实例化,但我感到困惑的是该方法的内容.

为什么比较currentTimeMillis()0?在什么情况下,这种比较会回归false

java jvm java-api

10
推荐指数
1
解决办法
611
查看次数

JList - 使用垂直滚动条而不是水平垂直包裹方向?

我正在尝试放置一个JList内部JScrollPane并按字母顺序列出垂直列中的条目,如下所示:

A D G
B E H
C F 
Run Code Online (Sandbox Code Playgroud)

但是当JList空间用完以显示更多条目时,我希望在垂直方向JScrollPane上滚动.

这在我使用时有效VERTICAL_WRAP.然而,似乎当我使用垂直包装时,我得到一个水平滚动条,当我使用时,HORIZONTAL_WRAP我得到我想要的滚动条,但是项目按照我不喜欢的顺序放置.我可以吃蛋糕吗?这是我正在尝试做的一个简单的例子.

在此输入图像描述

这是我能得到的最接近的,但我希望能够在保持垂直字母顺序的同时垂直滚动.

public class ScrollListExample {
    static List<String> stringList = new ArrayList<String>();
    static {
        for (int i = 0; i < 500; i++) {
            stringList.add("test" + i);
        }
    }

    public static void main(final String[] args) {
        final JFrame frame = new JFrame();
        final Container contentPane = frame.getContentPane();
        final JList list = new JList(stringList.toArray());
        list.setLayoutOrientation(JList.VERTICAL_WRAP);
        list.setVisibleRowCount(0);
        final …
Run Code Online (Sandbox Code Playgroud)

java user-interface swing jscrollpane jlist

8
推荐指数
1
解决办法
5777
查看次数

为什么JScrollPane中的JPanel不能滚动?

我有一个JPanel(黄色)放入JScrollPane.

PIC1

当我输入一些文本时JTextPane,它会调整大小,但垂直滚动条仍然不活动.yelowPanel.getSize()返回与之前相同的值.(您可以在redPanel上看到它).

PIC2

那我怎么刷新yellowPanel?我想垂直滚动面板.我试过了:

panelCreating.revalidate();
panelCreating.invalidate();
panelCreating.repaint();
Run Code Online (Sandbox Code Playgroud)

仅适用,panelCreating.setPreferredSize(new Dimension(333, 777));但我不知道要设置的大小.这取决于内容.

有一个小例子:

package swingtest;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;

public class SwingTest extends JFrame {

    public SwingTest() {
        initComponents();
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new SwingTest().setVisible(true);
            }
        });
    } …
Run Code Online (Sandbox Code Playgroud)

java swing jscrollpane

8
推荐指数
2
解决办法
3万
查看次数

Eclipse和javac之间奇怪的编译器差异

以下代码段(从实际代码中抽象出来)在Eclipse中编译和运行.

包1/Outer.java:

package package1;

import package1.Outer.Mid.Inner;
import package2.Bar;

public class Outer {
    final Mid mid = new Mid();

    public Outer() {
        mid.setInner(new Inner() {
            @Override public void foo() {
                System.out.println("In Outer.foo()");
            }
        });
    }

    public static class Mid implements Bar {
        private Inner inner;

        public void setInner(Inner inner) {
            this.inner = inner;
        }

        public Inner getInner() {
            return this.inner;
        }

        @Override
        public void bar() {}

        interface Inner {
            void foo();
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

包2/Bar.java:

package package2;

public interface Bar { …
Run Code Online (Sandbox Code Playgroud)

java javac

8
推荐指数
1
解决办法
333
查看次数

如何在eclipse中更改显示语言

我已经在http://mergedoc.sourceforge.jp/ eclipse 3.7上下载了一个副本,但是这个IDE是日文的,我想把它改成英文,有人可以帮帮我吗?

截图

eclipse

7
推荐指数
3
解决办法
5万
查看次数

如何告诉Proguard避免混淆JNA库类?

换句话说:我-keep应该用什么命令告诉Proguard避免混淆代表本机库的类?(因为JNA要求名称与等效的本机函数,struct等匹配)

java proguard jna

7
推荐指数
1
解决办法
2144
查看次数

可以封装中间流操作而不会破坏管道吗?

使用Java 8 Streams,是否可以以某种方式封装和重用中间流操作,而不会破坏流管道?

考虑来自Java Tutorial on streams的这个例子:

double average = roster
    .stream()
    .filter(p -> p.getGender() == Person.Sex.MALE)
    .mapToInt(Person::getAge)
    .average()
    .getAsDouble();
Run Code Online (Sandbox Code Playgroud)

假设我需要在整个代码中的不同位置使用filter和mapToInt操作.我可能想尝试并封装该逻辑,以便可以重复使用,例如:

IntStream maleAges(Stream<Person> stream) {
    return stream
        .filter(p -> p.getGender() == Person.Sex.MALE)
        .mapToInt(Person::getAge)
}
Run Code Online (Sandbox Code Playgroud)

这很好,但要使用它我可能不得不弄乱流管道.例如,如果我想要名叫Bob的男性的平均年龄:

double averageBob =
    maleAges(roster
        .stream()
        .filter(p -> "Bob".equals(p.getName()))
    )
    .average()
    .getAsDouble();
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法呢?我正在考虑这些方面的事情:

double averageBob = roster
    .stream()
    .filter(p -> "Bob".equals(p.getName()))
    .apply(this::maleAges) // Doesn't compile
    .average()
    .getAsDouble();
Run Code Online (Sandbox Code Playgroud)

java java-8 java-stream

7
推荐指数
2
解决办法
213
查看次数

TIME_TICK会在深度睡眠中播出吗?

Android是否会从深度睡眠中唤醒以进行广播ACTION_TIME_TICK?从实验来看,我认为不是,但我正在寻找一个明确的答案.

我的实验涉及注册一个简单BroadcastReceiver的更新TextView接收:

registerReceiver(new BroadcastReceiver() {
    int ctr = 0;
    @Override
    public void onReceive(Context context, Intent intent) {
        testView.setText("Time ticks: " + ++ctr);
    }
}, new IntentFilter(Intent.ACTION_TIME_TICK));
Run Code Online (Sandbox Code Playgroud)

在4个刻度处,我关闭了屏幕大约5分钟,然后将其重新打开,它读取了6个刻度.在13个刻度时,我将屏幕旋转了10分钟,然后将其重新打开,并且刻度数读数为14.无论我多长时间离开手机,这似乎只会增加1-2个刻度,这就是为什么我怀疑它不会在深度睡眠期间播放动作.

android

6
推荐指数
1
解决办法
6097
查看次数

需要无效的Swing组件的高度

基本设置是这样的:我有一个垂直的JSplitPane,我希望有一个固定大小的底部组件和一个调整大小的顶部组件,我通过调用完成setResizeWeight(1.0).在此应用程序中,有一个用于恢复"默认"窗口配置的按钮.窗口的默认高度是桌面高度,默认分隔符位置距离拆分窗格底部100个像素.

要将分隔符位置设置为100px,我将采用JSplitPane高度 - 100.问题是,在此之前我调整了JFrame的大小,并且由于代码处于按钮回调中,因此JSplitPane已失效但尚未调整大小.因此分配器位置设置不正确.

这是一个SSCCE.单击按钮两次以查看问题.第一次单击将调整窗口大小,但分隔符位置保持不变(相对于窗口底部).第二次单击正确移动分隔符,因为窗口大小没有改变.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSplitPane;

public class SSCCE {

    /**
     * @param args unused
     */
    public static void main(String[] args) {
        new SSCCE();
    }

    private final JFrame f = new JFrame("JSplitPane SSCE");
    private final JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT,true);

    public SSCCE() {
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        sp.add(new JLabel("top"));
        sp.add(new JLabel("bottom"));
        sp.setResizeWeight(1.0);

        f.getContentPane().add(sp);
        f.getContentPane().add(new JButton(new AbstractAction("Resize to Default") …
Run Code Online (Sandbox Code Playgroud)

java swing jsplitpane

6
推荐指数
1
解决办法
1417
查看次数