Skip to content

Commit 14b2cc9

Browse files
authored
Merge pull request giantray#61 from owen1190/master
what-is-the-difference-between-a-soft-reference-and-a-weak-reference-in-java.md lookup-enum-by-string-value.md
2 parents 2d7c9a0 + e719fac commit 14b2cc9

3 files changed

+175
-85
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,80 @@
1-
## 比较java枚举成员使用equal还是==
2-
3-
### 问题
4-
我知道Java枚举会被编译成一个包含私有构造参数和一堆静态方法的类,当去比较两个枚举的时候,总是使用equals()方法,例如:
5-
```java
6-
public useEnums(SomeEnum a)
7-
{
8-
if(a.equals(SomeEnum.SOME_ENUM_VALUE))
9-
{
10-
...
11-
}
12-
...
13-
}
14-
```
15-
除此之外,我也可以使用 == 替代equals() 方法
16-
```java
17-
public useEnums2(SomeEnum a)
18-
{
19-
if(a == SomeEnum.SOME_ENUM_VALUE)
20-
{
21-
...
22-
}
23-
...
24-
}
25-
```
26-
我有5年以上的java编程经验,并且我想我也懂得 == 和 equals() 之间的区别,但是我仍然觉得很困惑,哪一个操作符才是我该使用的。
27-
28-
### 答案
29-
30-
二者皆对,如果你看过枚举的源码,你会发现在源码中,equals也仅仅非常简单的 == 。
31-
我使用 == ,因为无论如何,这个左值是可以为 null的
32-
33-
34-
译者补充 java.lang.Enum 中Equals 代码:
35-
```java
36-
public final boolean equals(Object other) {
37-
return this==other;
38-
}
39-
```
40-
41-
42-
### 额外答案
43-
#### 能在枚举中使用 == 进行判断?
44-
答案是肯定的,因为枚举有着严格的实例化控制,所以你可以用 == 去做比较符,这个用法,在官方文档中也有明确的说明。
45-
46-
>JLS 8.9 Enums
47-
>An enum type has no instances other than those defined by its enum constants.
48-
>It is a compile-time error to attempt to explicitly instantiate an enum type. The final clone method in Enum >ensures that enum constants can never be cloned, and the special treatment by the serialization mechanism ensures >that duplicate instances are never created as a result of deserialization. Reflective instantiation of enum types >is prohibited. Together, these four things ensure that no instances of an enum type exist beyond those defined by >the enum constants.
49-
>Because there is only one instance of each enum constant, it is permissible to use the == operator in place of the >equals method when comparing two object references if it is known that at least one of them refers to an enum ?>constant. (The equals method in Enum is a final method that merely invokes super.equals on its argument and ?>returns the result, thus performing an identity comparison.)
50-
51-
#### 什么时候 == 和 equals 不一样?
52-
As a reminder, it needs to be said that generally, == is NOT a viable alternative to equals. When it is, however (such as with enum), there are two important differences to consider:
53-
通常来说 == 不是一个 equals的一个备选方案,无论如何有2个重要的不同处需要考虑:
54-
55-
##### == 不会抛出 NullPointerException
56-
```java
57-
enum Color { BLACK, WHITE };
58-
59-
Color nothing = null;
60-
if (nothing == Color.BLACK); // runs fine
61-
if (nothing.equals(Color.BLACK)); // throws NullPointerException
62-
```
63-
##### == 在编译期检测类型兼容性
64-
```java
65-
enum Color { BLACK, WHITE };
66-
enum Chiral { LEFT, RIGHT };
67-
68-
if (Color.BLACK.equals(Chiral.LEFT)); // compiles fine
69-
if (Color.BLACK == Chiral.LEFT); // DOESN'T COMPILE!!! Incompatible types!
70-
```
71-
72-
#### 什么时候使用 == ?
73-
Bloch specifically mentions that immutable classes that have proper control over their instances can guarantee to their clients that == is usable. enum is specifically mentioned to exemplify.
74-
具体来说,那些提供恰当实例控制的不可变类能够保证 == 是可用的,枚举刚好符合这个条件。
75-
76-
> Item 1: Consider static factory methods instead of constructors
77-
[...] it allows an immutable class to make the guarantee that no two equal instances exist: a.equals(b) if and only if a==b. If a class makes this guarantee, then its clients can use the == operator instead of the equals(Object) method, which may result in improved performance. Enum types provide this guarantee.
78-
79-
总而言之,在枚举比较上使用 == , 因为:
80-
1. 能正常工作
81-
2. 更快
82-
3. 运行时是安全的
83-
4. 编译期也是安全的
84-
85-
stackoverlfow链接:http://stackoverflow.com/questions/1750435/comparing-java-enum-members-or-equals
1+
# 比较java中枚举成员是用“==”还是equals()
2+
3+
## 问题
4+
java枚举被编译成带有私有构造器和一堆public的静态成员的类。当比较枚举中的两个成员时,经常使用.equals()方法,例如
5+
public useEnums(SomeEnum a)
6+
{
7+
if(a.equals(SomeEnum.SOME_ENUM_VALUE))
8+
{
9+
...
10+
}
11+
...
12+
}
13+
然而,偶然间使用“==”代替equals方法
14+
public useEnums2(SomeEnum a)
15+
{
16+
if(a == SomeEnum.SOME_ENUM_VALUE)
17+
{
18+
...
19+
}
20+
...
21+
}
22+
应该使用哪个呢?
23+
## 解答
24+
### 回答1
25+
技术上来说,都是对的,如果你看了equals的源码,它简单地遵从“==” ,然而我一般使用“==” 因为它对于空指针,比较安全
26+
### 回答2
27+
#### 能在枚举时使用用“==”吗?
28+
29+
可以,枚举值有小型实例控制,允许你用“==”去比较实例,在文档中有说明:
30+
31+
JLS 8.9 枚举
32+
一个枚举类型除了定义的那些枚举常量外没有其他实例了。
33+
试图明确地说明一种枚举类型是会导致编译期异常。在枚举中final clone方法确保枚举常量从不会被克隆,而且序列化机制会确保从不会因为反序列化而创造复制的实例。枚举类型的反射实例化也是被禁止的。总之,以上内容确保了除了定义的枚举常量之外,没有枚举类型实例。
34+
35+
因为每个枚举常量只有一个实例,所以如果在比较两个参考值,至少有一个涉及到枚举常量时,允许使用“==”代替equals()。(equals()方法在枚举类中是一个final方法,在参数和返回结果时,很少调用父类的equals()方法,因此是一种恒等的比较。)
36+
37+
这足够强力地支持Josh的建议,如果你坚持使用单例模式,最好的方法是用枚举类型强化单例属性(见Effective Java第二版中的第三条:用私有构造器或者枚举类型强化Singleton属性,或者单例模式的线程安全
38+
>http://stackoverflow.com/questions/2912281/thread-safety-in-singleton/
39+
40+
#### “==”和equals的区别
41+
通常情况下,==并不是可以替换equals,然而在枚举中是可以的。它们之间有两个重要的不同:
42+
43+
“==”从不会抛出空指针异常
44+
45+
46+
enum Color { BLACK, WHITE };
47+
48+
Color nothing = null;
49+
50+
if (nothing == Color.BLACK); // 正常运行
51+
52+
if (nothing.equals(Color.BLACK)); // 抛出空指
53+
针异常
54+
55+
在编译期,"=="会检查其类型的兼容性
56+
57+
enum Color { BLACK, WHITE };
58+
enum Chiral { LEFT, RIGHT };
59+
60+
if (Color.BLACK.equals(Chiral.LEFT)); // 编译正常
61+
if (Color.BLACK == Chiral.LEFT); // 无法编译,类型不兼容
62+
63+
#### 在适用时,“==”可以被使用吗
64+
65+
Bloch(effective java的作者)明确指出不可变类可以控制它们实例保证客户端“==”是可用的。枚举就被明确地证明了
66+
67+
考虑静态工厂方法代替构造器
68+
它使得不可变的类可以确保不会存在两个相等的实例,即当且仅当a==b的时候才有a.equals(b)为true。如果类保证了这一点,它的客户端可以使用“==”操作符来代替equals(Object)方法,这样可以提升性能。枚举类型保证了这一点
69+
70+
总之,在枚举中使用“==”优势:
71+
72+
- 能运行
73+
- 更快
74+
- 在运行期更安全
75+
- 在编译期更安全
76+
77+
备注:强有力的反击了那些认为foo.equals(bar)比foo==bar更有可读性的人们。
78+
79+
原文地址:
80+
> http://stackoverflow.com/questions/1750435/comparing-java-enum-members-or-equals

contents/lookup-enum-by-string-value.md

+57
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,59 @@
1+
<<<<<<< HEAD
2+
#通过String值查找enum中常量
3+
## 问题
4+
假设有一个枚举值
5+
public enum Blah
6+
{
7+
A,B,C,D
8+
}
9+
想通过一个String类型,找到所需要的枚举值。
10+
例如“A”->Blah.A
11+
是使用Enum.valueOf()方法吗?该如何使用
12+
## 回答
13+
Blah.valueOf("A")会得到Blah.A
14+
虽然api文档确实有静态方法valueOf()和values(),但是二者在编译期时才出现,而且在没出现在源程序中。
15+
例如可以采用Dialog.ModalityType显示了两种方法来处理这种情况。
16+
备注:Blah.valueOf("A")的方法是区分大小写,且不能含有空格。
17+
18+
如果String值与enum中不相同的查找方法:
19+
20+
public enum Blah
21+
{
22+
A("text1"),
23+
B("text2"),
24+
C("text3"),
25+
D("text4");
26+
private String text;
27+
Blah(String text)
28+
{
29+
this.text = text;
30+
}
31+
public String getText()
32+
{
33+
return this.text;
34+
}
35+
36+
public static Blah fromString(String text)
37+
{
38+
if (text != null)
39+
{
40+
for (Blah b : Blah.values())
41+
{
42+
if (text.equalsIgnoreCase(b.text))
43+
{
44+
return b;
45+
}
46+
}
47+
}
48+
return null;
49+
}
50+
}
51+
52+
备注:throw new IllegalArgumentException("No constant with text"+text+"found")会比直接抛出null更好
53+
54+
原文链接:
55+
> http://stackoverflow.com/questions/604424/lookup-enum-by-string-value#
56+
=======
157
## Java 中如何将 String 转换为 enum
258

359
###问题
@@ -104,3 +160,4 @@ stackoverflow链接
104160
http://stackoverflow.com/questions/604424/lookup-enum-by-string-value
105161
_译者:[MagicWolf](https://github.com/DaiDongLiang)_
106162

163+
>>>>>>> upstream/master
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Java中软引用和弱引用的区别
2+
## 问题
3+
题目就是问题
4+
5+
## 解答
6+
### 回答1
7+
从Ethan Nicholas的《Understanding Weak References》中
8+
9+
弱引用:
10+
放置一个弱引用的作用,不是强有力强制一个对象保存在内存中。弱引用允许利用垃圾收集者的能力去决定可达性,所以你不需要自己做,你只需要创建一个软引用:
11+
12+
WeakReference weakWidgt = new WeakReference(widgt);
13+
14+
然后在代码别的地方你可以使用 `weakWidget.get()` 来获取真实的 `Widgt` 对象,当然弱引用足以强大能抵制垃圾收集器,所以你也许发现(如果没有强引用指向widget)`weakWidget.get()`突然开始返回null
15+
16+
软引用
17+
18+
软引用就像弱引用一样,除了它不会着急将引用的对象扔出去。只有弱可达性的对象(这样的对象最强的引用只能是弱引用)将在下一次垃圾收集处理中被抛弃,但是软可达性的对象通常可以坚持一会。
19+
20+
软引用不要求与弱引用有什么不同,但是实际中,只要内存足够,软可达的对象通常会维持下去。对于缓存来说,这是个不错的基础,就像以上图像缓存描述,虽然可以让垃圾收集者担心对象是如何可达(一个强可达性的对象从不会从缓存中移除)和她们需要消耗多少内存
21+
22+
而且Peter Kessler备注到
23+
24+
Sun JRE 对待软引用和弱引用是不同的。如果内存是够用的。我们应坚持用软引用引用对象。一个细节是:对于客户端和服务器,JRE的政策是不同的:客户端,JRE试图保持通过清除软引用而不是扩大堆内存来使改变小点,而服务器端,JRE通过扩大堆内存让性能更好。没有一种通用的方法。
25+
26+
### 回答2
27+
弱引用对象很快被收集。如果GC发现一个对象是弱引用(只能通过弱引用可达),它会立刻清除弱引用对象。同样的,对于在程序保持关联信息的对象保持一个引用是不错的,像关于类的缓存存储的反射信息或一个对象的包装器等等。没有意义地跟随相连对象的任何事物都会被清除掉。当弱引用清除掉时,它会进入到引用队列中,同时丢弃关联的对象。你保持关于对象额外的信息,但是一旦对象引用不要了,信息也就不需要了。总之,在某些情境下,你可以创建WeakReference的子类,保持在WeakReference的子类中对象的额外信息。WeakReference的其他典型应用是与Map连接,以保持规范化的例子。
28+
29+
在另一方面,软引用有利于外部缓存,再创造资源,因为GC会延迟清理他们。它能保证所有软引用会在内存溢出之前被清除,所以它们不会造成内存溢出。
30+
31+
典型的使用例子是保持从一个文件内容解析形式。在你载入文件,解析和与解析过代表的根对象保持一个软引用的地方扩展系统。在你下次需要文件时,你试图通过软引用恢复。如果可以恢复,你会在其他地方载入、解析你分享的文件,如果同时GC清理掉,你也可以重新载入。这样的话,你利用空内存可以做到性能最优化,但是不要内存溢出。
32+
光保持一个软引用不会造成溢出。如果在另一方面你误用软引用,且弱引用被使用了(也就是说,你保持与较强引用的对象相连的信息,然后当引用对象被清除,你也丢弃信息),你可能会内存溢出,因为在进入引用队列时,也许碰巧没有及时丢弃相连的对象。
33+
34+
所以,使用软引用还是弱引用是取决于用法的。如果你的信息构造起来较为复杂,但是尽管如此仍想从别的数据再构造信息,使用软引用。如果你对一些数据的规范化实例保持引用,或者你想对一个“不拥有的”对象保持引用(就是防止被垃圾回收),这样就使用弱引用。
35+
36+
37+
原文:
38+
> http://stackoverflow.com/questions/299659/what-is-the-difference-between-a-soft-reference-and-a-weak-reference-in-java

0 commit comments

Comments
 (0)