论坛积分策略 论坛VIP区开放申请 我爱电脑万人签名活动 原声大碟520欢迎你 广告位招租
打印

[java] 关于Java初学者需要了解的几个基础问题

关于Java初学者需要了解的几个基础问题

对于这个系列里的问题,每个学Java的人都应该搞懂。当然,如果只是学Java玩玩就无所谓了。如果你认为自己已经超越初学者了,却不很懂这些问题,请将你自己重归初学者行列。
2 p, o7 i6 U( ?- q- Uwww.520diannao.com: e0 c/ [7 H2 p" W0 u; U
我爱电脑技术论坛: Z+ X5 v7 W* S% Y

- }6 _; @  @) g- o, c9 M电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站问题一:我声明了什么!
! @2 k- C$ j- ^9 E, r( i$ Q我爱电脑技术社区--打造最好的电脑技术自学交流平台电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站) s/ B0 c8 R9 Z+ S- \
我爱电脑技术论坛5 ^" S# I+ f- C
www.520diannao.com; |" e+ y* ~8 P# f; k7 G; r0 M
www.520diannao.com# `/ Y0 B- v: u# q' Z' O, d
String s = "Hello world!"; www.520diannao.com, |) K& c0 Y) s) v

. z4 B% K/ A, u7 A# o7 w电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
  s* M; R/ d; h4 J# w2 ]9 Gwww.520diannao.com
4 Q( C+ R4 c( F% Q我爱电脑技术论坛许多人都做过这样的事情,但是,我们到底声明了什么?回答通常是:一个String,内容是“Hello world!”。这样模糊的回答通常是概念不清的根源。如果要准确的回答,一半的人大概会回答错误。
3 i0 n: c3 J% E我爱电脑技术论坛
) Q$ q( P, m1 e9 B- M我爱电脑技术社区--打造最好的电脑技术自学交流平台9 M3 N  E& q& \5 \, }+ A# B
www.520diannao.com8 x- L; I0 N6 j8 ~1 O
这个语句声明的是一个指向对象的引用,名为“s”,可以指向类型为String的任何对象,目前指向"Hello world!"这个String类型的对象。这就是真正发生的事情。我们并没有声明一个String对象,我们只是声明了一个只能指向String对象的引用变量。所以,如果在刚才那句语句后面,如果再运行一句:
$ [" n) [- b! {( V5 {电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站. d) A% f2 t+ t8 M
www.520diannao.com( A5 |7 d9 F# v+ N! u& Q( ~' B

# Z3 w0 s5 _2 W9 L5 ~www.520diannao.com打造最好的电脑自学交流论坛; m( _- H/ q+ i1 Y: P
String string = s; 打造最好的电脑自学交流论坛* E# m0 w. b4 G8 l5 F  g. q
www.520diannao.com( G* t* p9 @$ A+ X# i

6 {$ C2 p" A+ V  ]! L1 g我爱电脑技术社区--打造最好的电脑技术自学交流平台
3 R9 l; i  B% _$ D; p' B. }% ]打造最好的电脑自学交流论坛我们是声明了另外一个只能指向String对象的引用,名为string,并没有第二个对象产生,string还是指向原来那个对象,也就是,和s指向同一个对象。 打造最好的电脑自学交流论坛& v% U1 h& W. F: y
我爱电脑技术论坛" o! {& t( J: C1 p% x  S

6 U* P( [, T9 L. \  o0 j2 H+ n电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
$ T( v- W: Q2 L4 z电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站问题二:"=="和equals方法究竟有什么区别? 我爱电脑技术社区--打造最好的电脑技术自学交流平台" D! O7 m" P9 v. _- y) S; T

5 w, A. S4 ]1 T+ B$ \: I/ J3 M! O8 V电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站$ X$ O. q5 K  H- s# d
我爱电脑技术社区--打造最好的电脑技术自学交流平台2 f" \- O0 w" c- s: i6 E1 T
==操作符专门用来比较变量的值是否相等。比较好理解的一点是: 电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站6 U: a2 ~: E3 X. Z6 b2 J+ l. [
www.520diannao.com( `" C" q0 C5 @7 @

% @, S9 M! q; l3 @; t4 }+ R9 F) D3 Dwww.520diannao.com2 u) v. z; @4 [" r: Q$ @7 l" p; R7 Z
打造最好的电脑自学交流论坛/ r. n/ x+ J+ @5 e; z# U
int a=10; 电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站; u6 x+ ]0 _. o- e; G$ o

8 ?3 s7 M( O* T8 S( @% f, ^6 |; _; q" A! j! |
int b=10;
  z+ N6 ~  C1 z  @, F8 \: }
6 G/ p! }. p2 z4 f& k打造最好的电脑自学交流论坛
* g* Y# {; _: r; bwww.520diannao.com电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站5 V. W3 g# `! @8 v& R
则a==b将是true。
" e# D9 b% a8 O5 ]
% C) E) R: l. X* C* l( e我爱电脑技术论坛
8 @# P9 t' M) w! }. r4 _我爱电脑技术社区--打造最好的电脑技术自学交流平台
7 A. ^4 d: G  u6 e6 o( B打造最好的电脑自学交流论坛但不好理解的地方是: - C2 R' x- `: ~3 e2 w" q" ^1 M
* _4 }! |' S6 Y) y; X

, ]% q( I3 X$ twww.520diannao.com打造最好的电脑自学交流论坛2 x3 w- u" u( ^) @

& f9 r9 E! {# m* f% F1 Bwww.520diannao.comString a=new String("foo");
# t) Y5 t3 J: i( M电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
$ E, r4 w4 x6 j4 s2 J打造最好的电脑自学交流论坛www.520diannao.com4 P. y+ j5 g- F& `
String b=new String("foo");
  w9 Z9 z& h6 c) H. t3 b/ s# m' ^打造最好的电脑自学交流论坛5 l/ y6 k+ ?* D

( p- u, b! z3 O1 J, @( R1 \' E( S打造最好的电脑自学交流论坛
( Y8 x" ]" D- |% V+ D  q则a==b将返回false。
9 W& F9 g) l8 ~2 G$ k, M打造最好的电脑自学交流论坛我爱电脑技术论坛5 r* E' Z3 W( f) f* V& p! u
# C, Z: r- P/ g0 z& B* n

6 Q$ d" |7 f) W: m2 {, Twww.520diannao.com根据前一帖说过,对象变量其实是一个引用,它们的值是指向对象所在的内存地址,而不是对象本身。a和b都使用了new操作符,意味着将在内存中产生两个内容为"foo"的字符串,既然是“两个”,它们自然位于不同的内存地址。a和b的值其实是两个不同的内存地址的值,所以使用"=="操作符,结果会是false。诚然,a和b所指的对象,它们的内容都是"foo",应该是“相等”,但是==操作符并不涉及到对象内容的比较。
) ?/ z- s' V" }0 s! _& [我爱电脑技术论坛, z3 b( r+ X/ `; P, J
打造最好的电脑自学交流论坛! b! X- s" F9 a0 d2 R3 q
我爱电脑技术论坛* t; x' l6 J8 U9 a0 F# X3 R
对象内容的比较,正是equals方法做的事。
3 a1 b: b7 L1 t/ _2 }我爱电脑技术社区--打造最好的电脑技术自学交流平台
7 z2 J# ?6 t4 g1 i. i$ b) s0 j电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
( {5 t- s' C$ E: v% W7 n7 g打造最好的电脑自学交流论坛
7 \# G  K5 }% K* |7 `6 J, {% j" I% G打造最好的电脑自学交流论坛看一下Object对象的equals方法是如何实现的: 我爱电脑技术社区--打造最好的电脑技术自学交流平台4 H/ s* y: Y3 ^6 a+ i

; ?/ }& g# @5 B6 e: H8 C( p" m打造最好的电脑自学交流论坛% u0 V7 l* y, c- z1 z6 F5 w
www.520diannao.com# f' c( C* w/ P- V

: f) e8 \$ W  Xwww.520diannao.comboolean equals(Object o){ www.520diannao.com8 w( U  v: k. r  [  W% I
) {/ d3 J2 G; g) p7 Z

  I8 `+ W8 m  Z  j3 q打造最好的电脑自学交流论坛
. C2 Z- X2 r3 ]* [www.520diannao.comreturn this==o; 电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站$ k) T4 i6 V+ ~7 O/ d1 {/ s

! \# h6 v/ i  L  ]! T' q* ^, M我爱电脑技术论坛' y2 d- \2 X5 L( d2 o+ b

8 r7 y3 I! C8 c- j# \) r打造最好的电脑自学交流论坛}
) k# f& I( i5 J8 }1 p  ]" g电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
5 k% S4 |6 D, E0 G( P7 O
) y5 J- X8 z1 ?1 [: X5 U1 I) s, c打造最好的电脑自学交流论坛
$ a1 J3 }1 ]: ]" \! h: I5 u我爱电脑技术社区--打造最好的电脑技术自学交流平台Object对象默认使用了==操作符。所以如果你自创的类没有覆盖equals方法,那你的类使用equals和使用==会得到同样的结果。同样也可以看出,Object的equals方法没有达到equals方法应该达到的目标:比较两个对象内容是否相等。因为答案应该由类的创建者决定,所以Object把这个任务留给了类的创建者。
, a; f/ G' f; g0 k3 u4 v$ Y  o4 ?打造最好的电脑自学交流论坛我爱电脑技术社区--打造最好的电脑技术自学交流平台6 V. S& w: m0 N; X
打造最好的电脑自学交流论坛! `% R  p; N8 s1 V. a' t

2 {/ K- }; X7 P9 G6 I我爱电脑技术论坛看一下一个极端的类:
+ D+ T7 \* a2 J9 R. r我爱电脑技术论坛我爱电脑技术社区--打造最好的电脑技术自学交流平台: _, V$ T. j9 h
我爱电脑技术社区--打造最好的电脑技术自学交流平台6 _: a5 s# L& }) y

2 T' Z  a+ o% G( x7 A9 I我爱电脑技术社区--打造最好的电脑技术自学交流平台电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站. t* N7 N5 W# B
Class Monster{
2 B# v: E4 `4 U0 U1 a* D/ U% ^' U, M打造最好的电脑自学交流论坛8 S2 s; J- D$ ~1 h! S( C: c  F- T
我爱电脑技术论坛, ?0 e4 g) i' N8 l7 ?6 k' M) H
private String content;
1 V. n4 |# c+ L
0 W- {* k' @# k, W! G/ Z+ A打造最好的电脑自学交流论坛2 O$ I2 M, Z3 [4 J) s4 w
...
2 R  J/ U+ L+ O+ S/ j
) ]. k" j* f$ z; v% B: M我爱电脑技术论坛" ~4 I/ J% o5 Y. k
boolean equals(Object another){ return true;}
; |0 {( z9 j' B/ d* V  O4 `打造最好的电脑自学交流论坛我爱电脑技术论坛7 j7 Y( a& m+ V+ t! T
# D! c) X3 v0 O; \. X% X8 p

: d' _3 G0 ?1 B8 ^3 y3 @打造最好的电脑自学交流论坛} 我爱电脑技术社区--打造最好的电脑技术自学交流平台1 Y8 i4 f' O# H; w
/ V& H) ?* f+ Y3 ?
打造最好的电脑自学交流论坛; j1 S. K0 H2 `! z2 t% }  E  @
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站& n- ~3 Z" S3 z7 s. Q. \7 G' J
我覆盖了equals方法。这个实现会导致无论Monster实例内容如何,它们之间的比较永远返回true。
! O  o: Y5 M' e. D. b% u我爱电脑技术论坛我爱电脑技术社区--打造最好的电脑技术自学交流平台6 S. P3 k7 V( ]8 \3 s" W9 h5 i
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站1 H. f! R/ A, A( }$ s2 h1 x  ~

" N5 I' l: f- r$ s% w5 N我爱电脑技术论坛所以当你是用equals方法判断对象的内容是否相等,请不要想当然。因为可能你认为相等,而这个类的作者不这样认为,而类的equals方法的实现是由他掌握的。如果你需要使用equals方法,或者使用任何基于散列码的集合(HashSet,HashMap,HashTable),请察看一下java doc以确认这个类的equals逻辑是如何实现的。
$ \" ?( o. v9 H* m. m4 b我爱电脑技术论坛www.520diannao.com1 n, |* P. E) V- K" q
我爱电脑技术社区--打造最好的电脑技术自学交流平台. t, _* E! g+ C4 `7 G8 n9 g6 A

: g; S0 B  X, a4 B  w" u& o我爱电脑技术论坛问题三:String到底变了没有? 电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站4 c6 B! e: f1 P1 ~# U

' B7 E, @* {0 O9 h0 n我爱电脑技术论坛打造最好的电脑自学交流论坛; e1 f4 Z" m$ C' M% e2 f4 |

+ u3 u2 t6 n7 R' B我爱电脑技术社区--打造最好的电脑技术自学交流平台没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。请看下列代码: + t6 z& Z/ E/ }# O; |/ ?
我爱电脑技术社区--打造最好的电脑技术自学交流平台% Z) n6 W: k4 A+ U3 _; }1 o: K, i& F

0 g% U+ d, a3 I( }# B$ v电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站我爱电脑技术论坛& n5 R+ A; J( o+ Q' [9 D
' A$ K" K4 p) f* s
String s = "Hello"; 打造最好的电脑自学交流论坛0 i8 l: l/ A1 \
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站" b% K" p' k5 y% C4 F9 u# A
我爱电脑技术论坛# `0 O# s7 T% b/ I$ [
s = s + " world!"; 1 V$ p; w: j3 R( E0 V
打造最好的电脑自学交流论坛5 g. o8 d# O) T6 Q

4 F1 P0 ^( m. I( d" Iwww.520diannao.comwww.520diannao.com. p6 z. M0 S8 J1 s: q& L+ ^
s所指向的对象是否改变了呢?从本系列第一篇的结论很容易导出这个结论。我们来看看发生了什么事情。在这段代码中,s原先指向一个String对象,内容是"Hello",然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。 www.520diannao.com8 w# s; ]# l: h- S* B
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站% g1 U/ P' c- ~4 }0 l

( D, E: w- S* t$ Z, Z电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站我爱电脑技术社区--打造最好的电脑技术自学交流平台' s7 X4 S! X4 I" i- D
通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。 - Y+ l, ^; p" z  {

4 ~' H% X2 j8 Z  X
# Q8 C( ?( ]/ X$ i打造最好的电脑自学交流论坛我爱电脑技术论坛: [7 x- h) ?( q# O" t  v
同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样做: 8 {/ }- A9 f- g- w* _, f# C4 n

& U& f8 \- D8 K" z3 i* m) [2 @2 N我爱电脑技术社区--打造最好的电脑技术自学交流平台
! X) L1 W* t+ E$ F) x我爱电脑技术社区--打造最好的电脑技术自学交流平台www.520diannao.com6 |/ v+ ^! z* `9 U* v1 g% E6 ~' o
打造最好的电脑自学交流论坛' m$ ?$ l2 P' r/ V
public class Demo { www.520diannao.com2 y# j3 z5 Q5 u- [6 b# u* L
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站, M1 M1 D+ `4 G1 l

7 O8 d  a' w: n" P7 i* u+ D电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站private String s; 我爱电脑技术论坛/ L2 O% L& Z* Q# I8 p5 Y4 C

6 q6 _' g4 r) X& u+ a! k我爱电脑技术社区--打造最好的电脑技术自学交流平台www.520diannao.com6 D( o; m9 U: o: `$ ^
...
+ f% Z, A6 C8 L! U4 P: j  Iwww.520diannao.com我爱电脑技术社区--打造最好的电脑技术自学交流平台& s6 {  J/ P. \8 F
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站5 O  z+ Q/ {' ~
public Demo { 打造最好的电脑自学交流论坛" i: V& U, K* i

( u) D9 D2 J7 |* K我爱电脑技术论坛6 a/ H  c$ O3 M' z
s = "Initial Value"; 电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站, C# R9 V9 w1 ^* y

' Z2 a, p' X6 Y$ D8 w; x电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站
% T  K3 _4 G% ~' d我爱电脑技术论坛}
( l0 O  ~8 K) @9 {9 N: K我爱电脑技术社区--打造最好的电脑技术自学交流平台我爱电脑技术社区--打造最好的电脑技术自学交流平台* ~$ x2 o% m- U! s  o" C; `) E/ p

8 e4 C4 M1 s2 b9 ^; owww.520diannao.com... www.520diannao.com3 \, ^- T5 q8 b! U6 d4 h

% g& S& {. {7 l0 s$ N3 W打造最好的电脑自学交流论坛. |2 x8 N8 K  w( \
} 打造最好的电脑自学交流论坛+ E& q2 b% Q& c: d( H' Q! M
我爱电脑技术社区--打造最好的电脑技术自学交流平台/ E% x$ b9 R0 ^  ]* s5 L/ P

  d& C1 R% s/ u, k) N4 q打造最好的电脑自学交流论坛www.520diannao.com& h' ~. L! ?( v! j# _1 k* H
而非 我爱电脑技术论坛, O' V* E8 z3 ?5 s, e
打造最好的电脑自学交流论坛* C! m$ N: V1 Z6 [* o

% o( K1 y8 n, b0 I; h) ~$ R  n8 h7 g+ f  _- c5 ]) q2 I

3 j2 `: l1 K' d* i7 R/ K我爱电脑技术论坛s = new String("Initial Value"); 我爱电脑技术论坛7 d7 D  D: f3 q& c9 ~9 h: R: i
2 N/ C. T5 S1 g# o) A0 G* ~
我爱电脑技术论坛; f% N' Y! m8 s0 Y  Q( a

2 [: j5 A1 c. p6 ?% iwww.520diannao.com后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的String类型属性s都指向同一个对象。 1 S! `7 q+ I' q5 d
电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站+ ]. }$ L: [4 n( `3 g) W# _! Q. V' R

! }  k# f/ D8 W- J我爱电脑技术社区--打造最好的电脑技术自学交流平台上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。
8 {* W' e$ D' |电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站电脑,技术,IT,学习,交流,网络安全,QQ,硬件,软件,编程,教程,建站& w. }' F/ S6 S! E
( y2 q$ u2 T% X( c+ F3 b: `; T/ v+ H
我爱电脑技术论坛+ E5 O& F: O7 |$ _( w
至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本,即StringBuffer。

TOP

看来我还是初学者啊

TOP

支持!!!!!!!!!!!!!!!!

TOP

不错 不错 学习了

TOP