我最近遇到了java @SafeVarargs注释.谷歌搜索使Java中的可变函数不安全的原因让我感到困惑(堆中毒?擦除类型?),所以我想知道一些事情:
是什么让可变参数Java函数在@SafeVarargs意义上不安全(最好以深入的例子的形式解释)?
为什么这个注释留给程序员自行决定?这不是编译器应该能够检查的东西吗?
是否有必须坚持一些标准,以确保他的功能确实安全?如果没有,确保它的最佳做法是什么?
我最近看到了一些利用这种语法的代码(亚马逊hadoop代码)
Foo bar = new Foo().setX(10).setY(11);
Run Code Online (Sandbox Code Playgroud)
我觉得那很好,所以我决定试一试.使我的setX()类型函数返回Foo而不是void放入return this;所有这些函数.这很好用.直到我尝试继承,这产生了一些结果.
我将给出一个具体的例子:我有两个类,Location有两个字段的类,x和y.和另一个Location3D继承自Location第三个字段的类,z.所有字段都使用上述方法作为其setter.
现在我想创建一个新的location3D实例并设置其字段,会发生什么
new Location3D().setZ(7).setY(6).setX(5)
Run Code Online (Sandbox Code Playgroud)
同时工作
new Location3D().setX(7).setY(6).setZ(5)
Run Code Online (Sandbox Code Playgroud)
没有.
by不起作用我的意思是返回的setY(6)是一个Location对象而不是一个location3D对象,因此没有setZ()方法!
在这个长篇介绍之后,我的问题是:这种形式的"setter stringing"可以使用继承而不强制调用者转换对象吗?如果是这样的话?
另外我确定这个术语比"setter stringing"更好,这是什么?
我有一个asynctask做某事,当它完成,我希望它广播它已完成.
通常我会这样做:context.sendBroadcast(new Intent(MYINTENT));但asynctask没有上下文.我已经看到了这个问题的一些答案,建议向asynctask发送对应用程序活动的上下文的引用.但如果用户旋转屏幕,则该引用很糟糕.并且手动维护引用是一个糟糕的解决方案(从创建asynctask的活动中需要太多,我无法控制).现在的问题是:
1)android为什么会这样设置?为什么在广播可以注册并由其他环境处理时,我甚至需要一个上下文来发送广播?
2)这个问题有一个很好的解决方案吗?(好=要求尽可能少地创建asynctask的活动,幸存轮换等等.).
假设我有一个文件test.c,其中包含:
char buffer1[1024];
int somefunction()
{
char buffer2[1024];
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
现在我知道buffer2是在属于某些函数调用的帧上的堆栈上分配的,但是在哪里分配了buffer1?
在某些SuperClass我有一个抽象的通用方法:
protected abstract <T extends Foo> T getFoo();
Run Code Online (Sandbox Code Playgroud)
在我的SubClass尝试覆盖它:
@Override
protected SubFoo getFoo() {
return new SubFoo();
}
Run Code Online (Sandbox Code Playgroud)
哪里 public class SubFoo extends Foo
在我的子类中getFoo我得到以下错误.
"类型安全:来自类型SubClass的getFoo()的返回类型SubFoo需要未经检查的转换以符合类型SuperClass中的T"
我的问题是:
1)是否存在不安全的情况?
2)如果没有,编译器是否应该能够解决这个问题?什么阻止编译器在编译时弄清楚SubFoo是Foo的子类?
3)有没有办法实现这样的事情,但是没有警告?
main()
{
printf( "%d\n" , 1/fork() );
}
Run Code Online (Sandbox Code Playgroud)
通过运行此应用程序我的输出是:0.
我知道父叉值是数字,而儿子值是0.
那么为什么我在分割1/0时没有任何问题呢?
我有一个带有字典的类,它将Type键映射到实现某个接口的对象IWhatever.
我希望创建一个泛型函数,它将Type作为输入,并返回映射到字典中该类型的对象.
就像是 :
public T get<T>(Type type)
Run Code Online (Sandbox Code Playgroud)
其中T是类型和类型实现的实例IWhatever.
我不想返回Object,甚至不想返回Iwhatever给定类型的对象.返回对象的类型可以在编译时明显地进行.所以我认为它应该是可能的.
我已经设法在java中这样做:
public T get<T>(Class<T extends IWhatever> type) { // implementation }
Run Code Online (Sandbox Code Playgroud)
有没有办法在C#中实现这一目标?如果没有,为什么不,你会建议什么选择?
我有多个相同长度的数组,我希望用零填充.让我们看看两种方法:
int i;
for(i=0;i<ARRAYSLENGTH;i++){
arr1[i]=0;
arr2[i]=0;
arr3[i]=0;
...
}
Run Code Online (Sandbox Code Playgroud)
memset所有数组归零.在最近的一次代码审查中,我被要求将选项1更改为选项2.这让我想知道,哪种方法更好?主要是:
2被认为比1更可读吗?
这两种方法在效率方面有何比较?(考虑memset通常在汇编中实现,但方法1仅为多个数组递增计数器一次).
我刚刚测试了以下场景,两个函数:
// method A
private void make(Object ...objects ){
System.out.println("varargs make");
}
// method B
private void make(){
System.out.println("non varargs make");
}
Run Code Online (Sandbox Code Playgroud)
跟电话make().
如果代码中只存在两种方法中的一种,那么它就是被调用的方法.但是,当两种方法都存在时,只调用方法B.
我还有两个理论问题和一个实际问题.
1)是什么让编译器"偏爱"B到A?
2)这是故意(标准)还是编译器实现的结果?
3)有没有办法"强制"编译器调用方法A?
我已经随机选择了1到1200之间的数字.如果你只能提出我只回答"是"或"否"的问题,那么在你得到我在脑海中选择的数字的答案之前,你需要问多少个问题?
函数重载如何节省内存?
以下两种类型的函数定义有什么区别,应该使用哪一种?
1)
ADD(a,b)
ADD(a,b,c)
ADD(a,b,c,d)
Run Code Online (Sandbox Code Playgroud)
2)
AddTwoNumbers(a,b)
AddThreeNumbers(a,b,c)
AddFourNumbers(a,b,c,d)
Run Code Online (Sandbox Code Playgroud)