我一直在阅读Java语言规范第3版,并且发现了我认为规范和javac编译器实现之间的差异.Eclipse编译器中存在相同的差异.
第15.16节讨论了强制转换表达式.如果参数类型无法通过强制转换转换为强制类型,那么它应该是编译时错误(第5.5节):
如果根据转换转换规则(第5.5节),操作数的编译时类型永远不会转换为强制转换运算符指定的类型,那么这是一个编译时错误.否则,在运行时,通过将转换转换为强制转换运算符指定的类型来转换操作数值(如果需要).
第5.5节讨论了转换.它给出了允许的转换类型列表.列表中特别缺少的是"取消装箱转换,然后加宽/缩小原始转换".但是,javac编译器(以及Eclipse编译器)似乎确实允许确切的转换序列.例如:
long l = (long) Integer.valueOf(45);
Run Code Online (Sandbox Code Playgroud)
......编译得很好.(有问题的强制转换是强制转换long
;参数是类型java.lang.Integer
,因此转换需要拆箱int
后跟扩展的原始转换).
同样地,根据JLS它不应该是可以从铸造byte
到char
,因为(根据5.1.4)需要加宽原语转换和一个基本收缩转换-然而,该铸造也由编译器允许的.
任何人都可以开导我吗?
编辑:自从问这个以来,我已经向Oracle 提交了一份错误报告.他们的反应是,这是"JLS中的一个小故障".
好吧,我已经阅读了很多这个问题的答案,但我有一个更具体的问题.以下面的代码片段为例.
public class GenericArray<E>{
E[] s= new E[5];
}
Run Code Online (Sandbox Code Playgroud)
在类型擦除之后,它变成了
public class GenericArray{
Object[] s= new Object[5];
}
Run Code Online (Sandbox Code Playgroud)
这段代码似乎运作良好.为什么会导致编译时错误?
此外,我从其他答案中得知,以下代码适用于同一目的.
public class GenericArray<E>{
E[] s= (E[])new Object[5];
}
Run Code Online (Sandbox Code Playgroud)
我读过一些评论说上面的代码是不安全的,但为什么它不安全?任何人都可以向我提供一个特定的例子,其中上面的代码导致错误?
另外,以下代码也是错误的.但为什么?擦除后似乎也能正常工作.
public class GenericArray<E>{
E s= new E();
}
Run Code Online (Sandbox Code Playgroud) 在另一个问题的讨论中,我得到一个例子,显然标识符的链接在常量表达式中影响了它的可用性:
extern char const a[] = "Alpha";
char constexpr b[] = "Beta";
char const g[] = "Gamma";
template <const char *> void foo() {}
auto main()
-> int
{
foo<a>(); // Compiles
foo<b>(); // Compiles
foo<g>(); // Doesn't compile
}
Run Code Online (Sandbox Code Playgroud)
最后一个错误(使用GCC)是:
test.cc: In function 'int main()':
test.cc:12:13: error: the value of 'g' is not usable in a constant expression
foo<g>(); // Doesn't compile
^
test.cc:3:16: note: 'g' was not declared 'constexpr'
char const g[] = "Gamma";
^
Run Code Online (Sandbox Code Playgroud)
我可能在前面的讨论中错过了这个例子的重要性,因为我认为它不可能仅仅是与之不同的foo<a>
联系 …
我负责部署在包括OS X在内的多个平台上的Java应用程序.在最新版本的应用程序中,我们为OS X分配了两个独立的软件包 - 一个使用Apple提供的JavaApplicationStub,另一个包含捆绑的JDK 7并使用内部生成的启动器(Oracle的JavaAppLauncher的修改).
问题是,对于后一个捆绑包,如果您尝试运行该应用程序,Mac OS X仍然坚持要安装Java 6.特别是消息说:
"要打开(应用程序),你需要一个Java SE 6运行时.你想现在安装吗?"
如果不安装Java SE 6,则无法运行该应用程序,尽管捆绑了JDK 7(如果安装了Java 6,它仍然使用捆绑的Java 7运行).
我正在努力弄清楚OS X如何决定应用程序需要Java?我尝试在Info.plist文件中重命名'Java'字典,并在Resources文件夹中重命名Java子文件夹,但没有成功.有没有人有任何想法?当然可以在不需要安装系统JDK的情况下使用捆绑的JDK运行应用程序吗?
我在java中使用RandomAccessFile:
file = new RandomAccessFile(filename, "rw");
...
file.writeBytes(...);
Run Code Online (Sandbox Code Playgroud)
如何确保将此数据刷新到操作系统?没有file.flush()方法.(请注意,我实际上并不期望它是物理写入的,我很满意它被刷新到操作系统,因此数据将在tomcat崩溃中存活,但不一定是意外的服务器断电).
我在Linux上使用tomcat6.
我有一个Java程序,它在一个单独的(非EDT)线程上执行紧密循环.虽然我认为Swing UI仍然应该响应,但事实并非如此.下面的示例程序显示了问题:单击"试用我"按钮应该在大约一半时间后弹出一个对话框,并且应该可以通过单击其任何响应立即关闭该对话框.相反,对话框需要更长的时间才能显示,并且/或者在单击其中一个按钮后需要很长时间才能关闭.
有没有人知道为什么EDT处理被延迟,即使只有一个繁忙的线程?
(请注意,尽管Thread.sleep
呼叫的各种建议是导致问题的原因,但事实并非如此.它可以被移除,问题仍然可以重现,尽管它表现得稍微不那么频繁并且通常表现出上述第二种行为 - 即非- 响应JOptionPane
对话而不是延迟对话框出现.此外,没有理由睡眠调用应该屈服于另一个线程,因为有如上所述的备用处理器核心 ; EDT可以在调用后继续在另一个核心上运行sleep
).
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class MFrame extends JFrame
{
public static void main(String[] args)
{
EventQueue.invokeLater(() -> {
new MFrame();
});
}
public MFrame()
{
JButton tryme = new JButton("Try me!");
tryme.addActionListener((e) -> {
Thread t = new Thread(() -> {
int a = 4;
for (int i = 0; i …
Run Code Online (Sandbox Code Playgroud) 的POSIX pselect
函数采取的信号掩码参数.在函数执行开始之前,信号掩码被"原子地"设置为当前掩码,并在函数返回时恢复.
这允许在函数执行时屏蔽未屏蔽的信号,并在函数返回时再次屏蔽.保证*如果捕获以这种方式未屏蔽的信号,该pselect
功能将被信号中断并且(除非用SA_RESTART
标志指定信号动作)将返回EINTR
错误.
(*:或者是吗?上面链接的文档中的语言似乎允许在由于看到文件准备就绪或超时而未被阻止之间pselect
以及用原始信息掩码替换信号掩码之间接收的信号不一定会导致EINTR
,因为EINTR
如果"功能在被阻止时中断......"是必需的 - 但是,这最终不会影响这个问题).
我的问题是:假设在pselect
执行期间暂时取消屏蔽两个独立的信号,是否有可能在pselect
函数返回之前捕获两个信号并恢复先前的信号掩码 - 或者是否有某种保证只捕获一个信号在这种情况下(另一个待定)?(出于问题的目的,假设SA_RESTART
没有为信号动作设置,并且在执行信号处理程序时,所有信号都被指定为屏蔽sigaction
).
我找不到任何暗示只能处理一个信号的东西,但我可能错过了一些东西,而且我正在编写一些代码,这将是一个非常有用的保证.我有兴趣知道POSIX本身是否有任何保证,以及不同的操作系统是否独立提供这样的保证.
例如,
int x[10];
int i = 0;
x = &i; //error occurs!
Run Code Online (Sandbox Code Playgroud)
根据C - A参考手册,数组名称不能是左值.因此,x不能是左值.但是,数组名称不能是左值的原因是什么?例如,为什么第三行发生错误?
我有一个表格,我希望阻止某些用户查看.我理解我应该能够使用视图执行此操作,即具有排除特定列的视图,并拒绝访问该表但允许访问视图(注意,用户无需更新表/视图).
我做不过要允许针对该领域的平等查询.如:
SELECT * FROM some_table_or_view WHERE hidden_field = 'some_value';
Run Code Online (Sandbox Code Playgroud)
澄清:
hidden_field
在一般查询中返回值hidden_field
值这可能吗?
(编辑:如果在除mysql之外的dbms中有解决方案,我也很高兴听到这个).
该kqueue的机制有一个事件标志,EV_RECEIPT
根据链接的手册页,其中:
...对于对kqueue进行批量更改而不会耗尽任何待处理事件非常有用.当作为输入传递时,它强制
EV_ERROR
始终返回.成功添加过滤器后,数据字段将为零.
然而,我的理解是,在不消耗任何挂起事件的情况下对kqueue进行批量更改是很简单的,只需将nevents
参数传递给0 kevent
,从而不从队列中抽取任何事件.考虑到这一点,为什么需要EV_RECEIPT
?
OS X的Apple文档中的一些示例代码实际上使用了EV_RECEIPT:
kq = kqueue();
EV_SET(&changes, gTargetPID, EVFILT_PROC, EV_ADD | EV_RECEIPT, NOTE_EXIT, 0, NULL);
(void) kevent(kq, &changes, 1, &changes, 1, NULL);
Run Code Online (Sandbox Code Playgroud)
但是,看到changes
在kevent
调用之后从未检查过数组,我完全不清楚为什么EV_RECEIPT
在这种情况下使用它.
EV_RECEIPT真的有必要吗?它在什么情况下真的有用?
我有一个 C++ 程序,我在其中使用模板元编程来生成要“通过网络”发送的小型二进制格式数据包,与分配固定大小缓冲区和复制各种数据的更幼稚的方法相比,它提供了更好的安全性和清晰度使用手工计算的偏移量将项目放入其中。
int foo(int fd, long long data1, float f1)
{
auto m = membuf()
.append<char>(0xAA).append<char>(0xBB) // header
.append(data1)
.append(f1)
.append(555); // in the pipe (arbitary extra data)
return write(fd, m.data(), m.size());
}
Run Code Online (Sandbox Code Playgroud)
这将发送一个由两个字节0xAA
和组成的数据包0xBB
,(例如)来自 的 8 个字节、来自 的data1
4 个字节f1
和形成 的 4 个字节555
。(等的实际大小int
当然取决于编译器/架构细节,但我也可以使用例如uint64_t
类型进行精确控制)。
(注意: 的完整实现membuf
与问题无关,但如果感兴趣,您可以在此处查看:https : //godbolt.org/z/sr0Cuu)
本案的重要特征是:
碰巧的是,这被编译成一个非常有效的指令序列,它只是在堆栈上分配缓冲区并将每个值写入其中的正确位置:
foo(int, long long, float):
subq $40, %rsp
movl …
Run Code Online (Sandbox Code Playgroud) class A {
public static void main(String args []){
int val = (int) ((Math.random) * 5);
String res = new String [ ]{"Rahul","Javed","Kunal","Ram"}[val];
System.out.println(res);
}
}
Run Code Online (Sandbox Code Playgroud)
当val的值为1时,打印了"Javed" - 但是在"String res ="表达式的末尾如何以及什么是[val].