它在JDK的很多类中都很常见,只有几个例子:
通常它们是私有本机方法(如Thread类),但有时它们只是私有(Properties类)
如果有人知道背后是否有任何历史,我只是好奇.
在以下示例中,有两个功能相同的方法:
public class Question {
public static String method1() {
String s = new String("s1");
// some operations on s1
s = new String("s2");
return s;
}
public static String method2() {
final String s1 = new String("s1");
// some operations on s1
final String s2 = new String("s2");
return s2;
}
}
Run Code Online (Sandbox Code Playgroud)
但是在first(method1)中,字符串"s1"显然可用于return语句之前的垃圾收集.在第二个(method2)字符串中,"s1"仍然可以访问(虽然从代码审查预期它不再使用).
我的问题是 - 在jvm规范中是否有任何内容表明,一旦变量在堆栈中未使用,它可用于垃圾收集?
编辑: 有时变量可以像完全渲染图像一样引用对象,并且会对内存产生影响.
我是因为实际考虑而问的.我在一个方法中有大量内存贪婪的代码,并且只是通过将此方法分成几个小方法来思考我是否可以帮助JVM(一点点).
我真的更喜欢没有重新分配的代码,因为它更容易阅读和推理.
更新:按 jls-12.6.1:
Java编译器或代码生成器可以选择设置将不再用于null的变量或参数,以使此类对象的存储可能更快地回收
所以看起来GC可以声明仍然可见的对象.我怀疑,然而这种优化是在离线编译期间完成的(它会搞砸调试),而且很可能是由JIT完成的.
根据JSR-133,不可变对象是线程安全的,不需要同步.但是,可以使用反射更新最终字段的值:
package com.stackoverflow;
import java.lang.reflect.Field;
public class WhatsGoingOn {
static class Immutable {
private final int value;
public Immutable(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
final Immutable immutable = new Immutable(Integer.MIN_VALUE);
final Field f = Immutable.class.getDeclaredField("value");
f.setAccessible(true);
System.out.println(immutable.getValue());
f.set(immutable, Integer.MAX_VALUE);
System.out.println(immutable.getValue());
}
}
Run Code Online (Sandbox Code Playgroud)
鉴于依赖于反射的框架数量(Spring和Hibernate只有少数),我很好奇规范说明了这个场景.例如,如果我将字段更新放入synchronized块中将保证其他线程中的可见性,或者值将根据spec的最终版本缓存在寄存器中.
http://download.oracle.com/otndocs/jcp/memory_model-1.0-pfd-spec-oth-JSpec/
List<String> list = new ArrayList(); 将导致编译器警告.
但是,以下示例编译时没有任何警告: List<String> list = new ArrayList<>();
我很好奇为什么需要引入钻石操作员.为什么不只是对构造类型推断,如果类型参数是不存在(因为它已经在Java静态方法做,像谷歌番石榴集合库开发)
编辑:使用millimoose答案作为起点我查看了实际上是什么类型的擦除,它不只是删除所有类型信息.编译器实际上做了一些(从官方文档复制):
考虑下面的代码狙击:
package sync;
public class LockQuestion {
private String mutable;
public synchronized void setMutable(String mutable) {
this.mutable = mutable;
}
public String getMutable() {
return mutable;
}
}
Run Code Online (Sandbox Code Playgroud)
在Time1线程Thread1将更新'mutable'变量.在setter中需要同步,以便将内存从本地缓存刷新到主内存.在时间Time2(Time2> Time1,没有线程争用)线程Thread2将读取mutable的值.
问题是 - 我需要在getter之前进行同步吗?看起来这不会导致任何问题 - 内存应该是最新的,Thread2的本地缓存内存应该由Thread1无效和更新,但我不确定.
java concurrency multithreading locking concurrent-programming
执行
user@EWD-MacBook-Pro:~$ export property.name=property.value
Run Code Online (Sandbox Code Playgroud)
给我
-bash: export: `property.name=property.value': not a valid identifier
Run Code Online (Sandbox Code Playgroud)
是否可以在其中包含点的系统属性?如果是这样的话怎么样?
在Oracle的官方文档 HeapDumpOnOutOfMemoryError选项中使用加号和减号指定.我只是很好奇它们代表什么,因为它没有在官方用户指南中解释
需要一个SQL查询来进行Oracle用户的克隆.作为源我有用户具有所有必要的权限.我想知道是否可以创建相同的一个,但在同一个数据库中使用不同的用户名.
看看源代码.
有可能是背后的正当理由,但它是奇怪的是,我所能做的hibernate.deleteAll和hibernate.loadAll,但不hibernate.saveOrUpdateAll(相信我能做到,实际上,但是,如果这种方法已不意味着它会在下一版本中消失)
我真的很喜欢guava库如何允许简单的单行检查null:
public void methodWithNullCheck(String couldBeNull) {
String definitelyNotNull = checkNotNull(couldBeNull);
//...
}
Run Code Online (Sandbox Code Playgroud)
遗憾的是,对于简单的参数检查,您至少需要两行代码:
public void methodWithArgCheck(String couldBeEmpty) {
checkArgument(!couldBeEmpty.isEmpty());
String definitelyNotEmpty = couldBeEmpty;
//...
}
Run Code Online (Sandbox Code Playgroud)
但它是可以添加方法,它可以做参数校验和,如果校验成功返回一个值.以下是检查的示例以及如何实施:
public void methodWithEnhancedArgCheck(String couldBeEmpty) {
String definitelyNotEmpty = EnhancedPreconditions.checkArgument(couldBeEmpty, !couldBeEmpty.isEmpty());
//...
}
static class EnhancedPreconditions {
public static <T> T checkArgument(T reference, boolean expression) {
if (!expression) {
throw new IllegalArgumentException();
}
return reference;
}
}
Run Code Online (Sandbox Code Playgroud)
我只是想知道是通过设计,是否值得为此提出功能请求.
编辑:@Nizet,是的,检查方法可能是笨拙的.但是,对构造函数中的null进行检查看起来非常好,并且节省了调试NPE所花费的大量时间:
public class SomeClassWithDependency {
private final SomeDependency someDependency;
public SomeClassWithDependency(SomeDependency someDependency) {
this.someDependency …Run Code Online (Sandbox Code Playgroud)