根据文档,该方法String.valueOf(Object obj)返回:
如果参数是
null,那么一个字符串等于"null"; 否则,obj.toString()返回值.
但是当我尝试这样做时怎么样:
System.out.println("String.valueOf(null) = " + String.valueOf(null));
Run Code Online (Sandbox Code Playgroud)
它会引发NPE而不是?(如果你不相信,请亲自尝试!)
Exception in thread "main" java.lang.NullPointerException
at java.lang.String.(Unknown Source)
at java.lang.String.valueOf(Unknown Source)
怎么会发生这种情况?文档对我说谎吗?这是Java中的一个主要错误吗?
简单的问题,如何使这段代码工作?
public class T {
public static void main(String[] args) throws Exception {
new T().m();
}
public // as mentioned by Bozho
void foo(String... s) {
System.err.println(s[0]);
}
void m() throws Exception {
String[] a = new String[]{"hello", "kitty"};
System.err.println(a.getClass());
Method m = getClass().getMethod("foo", a.getClass());
m.invoke(this, (Object[]) a);
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
class [Ljava.lang.String;
Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
Run Code Online (Sandbox Code Playgroud) Java varargs实现中似乎存在一个错误.当方法使用不同类型的vararg参数重载时,Java无法区分适当的类型.
它给了我一个错误 The method ... is ambiguous for the type ...
请考虑以下代码:
public class Test
{
public static void main(String[] args) throws Throwable
{
doit(new int[]{1, 2}); // <- no problem
doit(new double[]{1.2, 2.2}); // <- no problem
doit(1.2f, 2.2f); // <- no problem
doit(1.2d, 2.2d); // <- no problem
doit(1, 2); // <- The method doit(double[]) is ambiguous for the type Test
}
public static void doit(double... ds)
{
System.out.println("doubles");
}
public static void doit(int... is)
{
System.out.println("ints"); …Run Code Online (Sandbox Code Playgroud) 我记得我在某个地方有红色你可以创建一个带有无穷无尽的参数的方法.问题是我不记得怎么做了.我记得它是这样的:
private void method(int arguments...)
{
//method body
}
Run Code Online (Sandbox Code Playgroud)
我确定有" ...".而且我记得你打电话的时候method你可以这样称呼它:
method(3232);或者method(123,23,12);
如果有人理解我在说什么,请告诉我该怎么做.
以下代码与Eclipse完美编译,但无法使用javac进行编译:
public class HowBizarre {
public static <P extends Number, T extends P> void doIt(P value) {
}
public static void main(String[] args) {
doIt(null);
}
}
Run Code Online (Sandbox Code Playgroud)
我简化了代码,所以现在根本不使用T. 不过,我没有看到错误的原因.由于某种原因,javac决定T代表Object,然后抱怨Object不符合T的界限(这是真的):
HowBizarre.java:6:不兼容的类型; 推断类型参数java.lang.Number,java.lang.Object不符合类型变量的范围P(T)
发现:
<P,T>无效要求:无效
Run Code Online (Sandbox Code Playgroud)doIt(null); ^
请注意,如果我将null参数替换为非null值,则编译正常.
哪个编译器行为正确,为什么?这是其中之一的错误吗?
编码我来检查Java的vararg性能.
我写下面的测试代码:
public class T {
public static void main(String[] args) {
int n = 100000000;
String s1 = new String("");
String s2 = new String("");
String s3 = new String("");
String s4 = new String("");
String s5 = new String("");
long t = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
foo();
}
System.err.println(System.currentTimeMillis() - t);
t = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
baz(s1, s2, s3, s4, s5);
}
System.err.println(System.currentTimeMillis() …Run Code Online (Sandbox Code Playgroud) "API设计就像性:做出一个错误并在你的余生中支持它" (Josh Bloch在Twitter上)
Java库中存在许多设计错误.Stack extends Vector(讨论),我们无法在不造成破损的情况下解决这个问题.我们可以尝试弃用Integer.getInteger(讨论),但它可能会永远存在.
尽管如此,某些类型的改装可以在不造成破损的情况下完成.
有效的Java第2版,第18项:首选接口到抽象类:现有的类可以很容易地进行改进,以实现新的接口".
例如:String implements CharSequence,Vector implements List,等.
有效的Java第2版,第42项:明智地使用varargs:您可以改进现有方法,该方法将数组作为其最终参数,而不是对现有客户端采取varags.
一个着名的例子是Arrays.asList引起混淆(讨论),但没有破坏.
这个问题是关于不同类型的改造:
void不破坏现有代码的情况下改进返回方法的方法?我最初的预感指向是,因为:
void退货换货是合法的(但不是相反!)Class.getMethod也不会在返回类型上区分但是,我希望听到其他在Java/API设计方面经验丰富的人进行更全面的分析.
正如标题中所建议的那样,一个动机是促进流畅的界面风格编程.
考虑这个简单的代码片段,它打印一个混洗的名称列表:
List<String> names = Arrays.asList("Eenie", "Meenie", "Miny", "Moe");
Collections.shuffle(names);
System.out.println(names);
// prints e.g. [Miny, Moe, Meenie, Eenie]
Run Code Online (Sandbox Code Playgroud)
已经Collections.shuffle(List)被宣布为返回输入列表中,我们可以这样写:
System.out.println(
Collections.shuffle(Arrays.asList("Eenie", …Run Code Online (Sandbox Code Playgroud) 看看Guava的ImmutableList(和其他一些类),你会发现很多重载的of方便方法("返回包含给定元素的不可变列表,按顺序."),它们采用不同数量的参数:
...
public static <E> ImmutableList<E> of(E e1, E e2, E e3)
public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4)
public static <E> ImmutableList<E> of(E e1, E e2, E e3, E e4, E e5)
...
Run Code Online (Sandbox Code Playgroud)
一直到这个:
public static <E> ImmutableList<E> of(E e1,
E e2,
E e3,
E e4,
E e5,
E e6,
E e7,
E e8,
E e9,
E e10,
E e11,
E e12,
E... others)
Run Code Online (Sandbox Code Playgroud)
我的一些同事认为这很愚蠢,想知道为什么不只有一种方法:of(E... elements).他们怀疑这是一个不良导向的性能"优化",属于"你认为你比编译器更聪明"的类别,或类似的东西. …
我正在用Java更新遗留代码库,我找到了这样的一行:
Object arg[] = { new Integer(20), new Integer(22) };
Run Code Online (Sandbox Code Playgroud)
那条线引起了我的注意,因为我习惯了这种代码:
Object[] arg = { new Integer(20), new Integer(22) };
Run Code Online (Sandbox Code Playgroud)
这里的数组内容并不重要.我很好奇变量名旁边的括号与类名旁边的括号.我在Eclipse(使用Java 5)中尝试过,这两行对编译器都有效.
这些声明之间有什么区别吗?
在Java语言规范的第15.12.2.5节中,它讨论了如何在具有固定arity的方法和可变arity方法(即varargs)中选择最具体的方法.
我在JLS中找不到的是关于两个方法之间的决定,其中一个是固定的arity,另一个是变量arity.例如:
public interface SomeApi {
public String getSomething(String arg); // method 1
public String getSomething(String ... args); // method 2
}
Run Code Online (Sandbox Code Playgroud)
按照人们的预期编译就好(由Yoni概述的原因如下).这个调用代码也编译:
SomeApi api = ...
Object o = api.getSomething("Hello");
Run Code Online (Sandbox Code Playgroud)
如果你运行它,method #1(即非varargs方法)被调用.为什么这个调用代码没有含糊不清?为什么固定arity方法比变量arity方法更具体?有人能指出我对规范的相关部分吗?
java ×9
api-design ×2
null ×2
overloading ×2
arguments ×1
arrays ×1
c# ×1
compilation ×1
declaration ×1
eclipse ×1
generics ×1
guava ×1
jls ×1
jvm ×1
methods ×1
performance ×1
reflection ×1