amountStr 是一个偶尔包含表示为字符串的double值的值.
我想用Double.parseDouble它来读取double变量:amountDbl.
this.amountDbl = Double.parseDouble(amountStr);
Run Code Online (Sandbox Code Playgroud)
它似乎扔了一个NullPointerExceptionif amountStr没有价值.
这是否意味着我每次都必须写这样的支票?
if(amountStr!=null)
this.amountDbl = Double.parseDouble(amountStr);
Run Code Online (Sandbox Code Playgroud)
因为我的代码中有这么多这样的语句,所以我希望有一种更简洁的方法来做这个检查(或者避免它).
通常,我会遇到代码,其中重复使用/滥用Getter方法来获取某些值或将其作为方法参数传递,例如:
public class Test {
public void someMethod() {
if(person.getName() != null && person.getName().equalsIgnoreCase("Einstein")) {
method1(person.getName());
}
method2(person.getName());
method3(person.getName());
method4(person.getName());
}
}
Run Code Online (Sandbox Code Playgroud)
我通常编码,如下所示:
public class Test {
public void someMethod() {
String name = person.getName();
if(name != null && name.equalsIgnoreCase("Einstein")) {
method1(name);
}
method2(name);
method3(name);
method4(name);
}
Run Code Online (Sandbox Code Playgroud)
在我看来,将getter分配给变量并使用它有很大的内存/性能优势,因为Getters是Java方法并使用堆栈帧.编码方式真的有相当大的优势吗?}
我最近偶然发现了使用Java反射更改私有静态最终字段并测试了polygenelubricants的EverythingIsTrue类,工作正常,System.out.format("Everything is %s", false);打印Everything is true确实.但是当我改变代码时
public class EverythingIsTrue {
public static final boolean FALSE = false;
static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
public static void main(String[] args) throws Exception {
setFinalStatic(EverythingIsTrue.class.getField("FALSE"), true);
System.out.format("Everything is %s", FALSE);
}
}
Run Code Online (Sandbox Code Playgroud)
它打印
Everything is false
Run Code Online (Sandbox Code Playgroud)
有人知道为什么吗?setFinalStatic实际上是否有效?
我听说是这种情况,但我找不到确定的在线资源来确认.
背景:一位同事喜欢制作他的局部变量final.他这样做的原因之一是表现.我的论点是,Java的HotSpot Just In Time编译器会自动检测不变的局部变量并制作它们final,所以自己做这个没有性能上的好处.
请注意,我不是在问局部变量是否是一个好的编码实践final,因为已经有很多(非主题)SO问题.
编辑:mrhobo为优化整数文字的字节码提出了一个很好的观点.我应该给出一个我正在谈论的代码类型的例子,我的问题是:
Object doSomething(Foo foo) {
if (foo == null) {
return null;
}
final Bar bar = foo.getBar();
final Baz baz = this.bazMap.get(bar);
return new MyObject(bar, baz);
}
Run Code Online (Sandbox Code Playgroud)
您是否认为在这种情况下会发生相同类型的优化,因为bar并且baz都标记了final?或者,HotSpot会自动检测到它们是否在方法范围内没有变化,并将它们视为final无论如何?
共识似乎是将成员变量标记为final有一个性能优势,因为它们永远不需要从主内存重新加载.我的问题是,当变量无法改变时,javac或Hotspot会自动为我做这件事.例如,javac将在下面的这堂课中制作'x'决赛......
public class MyClass {
private String x;
MyClass(String x) {
this.x = x;
}
public String getX() {
return x;
}
}
Run Code Online (Sandbox Code Playgroud)
在次要问题上,有没有人提出经验证据表明成员最终会使代码运行得更快?在进行远程调用或数据库查找的任何应用程序中,任何好处肯定都可以忽略不计?
我看了这篇文章.看起来很好.然而,当HotSpot(不依赖于服务器或客户端或不依赖Sun版本)使代码内联时,作者或其他有意识的人会告诉我编码技巧.
我有一个以接口为根的类层次结构,并使用抽象基类实现.它看起来像这样:
interface Shape {
boolean checkFlag();
}
abstract class AbstractShape implements Shape {
private boolean flag = false;
protected AbstractShape() { /* compute flag value */ }
public final boolean checkFlag() { return flag; }
}
interface HasSides extends Shape {
int numberOfSides();
}
interface HasFiniteArea extends Shape {
double area();
}
class Square extends AbstractShape implements HasSides, HasFiniteArea {
}
class Circle extends AbstractShape implements HasFiniteArea {
}
/** etc **/
Run Code Online (Sandbox Code Playgroud)
当我使用VisualVM对正在运行的代码进行采样时,似乎AbstractShape.checkFlag()从不内联并占用了总程序运行时间的14%,这对于一个简单的方法来说是个淫秽,即使对于一个经常调用的方法也是如此.
我在基类上标记了方法final,并且(当前)实现"Shape"接口的所有类都扩展了AbstractShape.
我能正确解释VisualVM样本结果吗?有没有办法说服JVM内联这个方法,还是我需要撕掉接口并使用抽象基类?(我不愿意,因为层次结构包括像HasFiniteArea和HasSides这样的接口,这意味着层次结构没有完美的树形式)
编辑:要清楚,这是一种在任何宇宙中 …
java ×8
jvm-hotspot ×3
jvm ×2
c++ ×1
coding-style ×1
final ×1
getter ×1
inline ×1
inlining ×1
jit ×1
optimization ×1
performance ×1