ජාවා එනුම් සාමාජිකයින් සංසන්දනය කිරීම: == හෝ සමාන ()?


1745

ජාවා එනුම් පුද්ගලික සම්පාදකයින් සහ පොදු ස්ථිතික සාමාජිකයන් සමඟ පන්තිවලට සම්පාදනය කර ඇති බව මම දනිමි. දී ඇති enum හි සාමාජිකයන් දෙදෙනෙකු සංසන්දනය කිරීමේදී, මම සෑම විටම භාවිතා කර ඇත .equals(), උදා

public useEnums(SomeEnum a)
{
    if(a.equals(SomeEnum.SOME_ENUM_VALUE))
    {
        ...
    }
    ...
}

කෙසේ වෙතත්, ==.equals () වෙනුවට සමාන ක්‍රියාකරු භාවිතා කරන කේතයක් මට හමු විය :

public useEnums2(SomeEnum a)
{
    if(a == SomeEnum.SOME_ENUM_VALUE)
    {
        ...
    }
    ...
}

මා භාවිතා කළ යුත්තේ කුමන ක්‍රියාකරුද?


7
මම මේ හා සමාන ප්‍රශ්නයක් පැකිලී ගියෙමි
මැට් බෝල්

39
== හි තවත් විශාල වාසියක් සඳහන් නොකිරීමේ සියලු පිළිතුරු වල (විශේෂයෙන් බහුජනක උත්පාදක වලින් == ක්‍රියා කරන්නේ ඇයිද යන්න විස්තරාත්මකව විස්තර කිරීම) පුදුමයට කරුණකි: එමඟින් එනූම් ක්‍රියා කරන ආකාරය පැහැදිලි කරයි (ස්ථාවර සිංගල්ටන් කට්ටලයක් ලෙස) වස්තු). සමානාත්මතාවයෙන් එය එකම එනුම් 'විකල්ප' වටා පාවෙන අවස්ථා කෙසේ හෝ තිබිය හැකි යැයි සිතීමට කෙනෙකු යොමු කරයි.
ස්ටුවර්ට් රොසිටර්

6
එය සරලව තබා ගන්න. "==" වඩා කියවිය හැකි අතර එය ක්‍රියාත්මක වන්නේ එනූම්ස් පෙරනිමියෙන් සිංගල්ටන් නිසාය. Ref
lokesh

Answers:


1587

දෙකම තාක්ෂණික වශයෙන් නිවැරදි ය. ඔබ සඳහා ප්‍රභව කේතය දෙස බැලුවහොත් .equals(), එය සරලවම කල් දමයි ==.

==කෙසේ වෙතත්, එය ශුන්‍ය ආරක්ෂිත වනු ඇති බැවින් මම භාවිතා කරමි .


64
පුද්ගලිකව, == භාවිතා කිරීමට හේතුවක් ලෙස සඳහන් කර ඇති 'ශුන්‍ය ආරක්ෂාව' මා කැමති නැත.
Nivas

260
Iv නිවාස්: ඇයි නැත්තේ? ඔබේ තර්කවල අනුපිළිවෙල ගැන කරදර වීමට ඔබ කැමතිද (එය අදාළ වන්නේ පැස්කල්ගේ පිළිතුරෙහි මෙන් වමේ සිට නියතයන් සංසන්දනය කිරීම සඳහා පමණි). අගයක් ඇතුළත් කිරීමට පෙර .equals()එය අහෝසි නොවන බව නිතරම පරීක්ෂා කිරීමට ඔබ කැමතිද ? මම දන්නවා නැහැ කියලා.
මැට් බෝල්

87
ඔබේ කේතය කියවන විට, ඔහු / ඇය ඉවත්ව ගොස් අදාළ වර්ගය සඳහා ප්‍රභවය දෙස බලන තෙක් "==" පා er කයාට වැරදියි කියා මතක තබා ගන්න. ඒ අර්ථයෙන් ගත් කල, ".equals ()" කියවීම අඩු අවධානයක් යොමු කරයි.
කෙවින් බෝරිලියන්

60
E කෙවින් - ඔබ ප්‍රභවය බැලීමේදී සෘජුවම වර්ග බැලීමට ඉඩ දෙන IDE එකක් භාවිතා නොකරන්නේ නම්, ඔබ ඔබම රවටා ගනී - නිසි IDE සමඟ ගැටළුවක් නොවේ.
MetroidFan2002

64
සමහර විට කේතය ප්‍රතිනිර්මාණය වන අතර පන්තියක් මගින් එනූමයක් ප්‍රතිස්ථාපනය වීමට ඉඩ ඇත, එම අවස්ථාවේදී == තවදුරටත් නිවැරදි බවට සහතික නොවන අතර සමානාත්මතාවය අඛණ්ඩව බාධාවකින් තොරව ක්‍රියා කරයි. මේ හේතුව නිසා, සමානාත්මතාවය පැහැදිලිවම වඩා හොඳ තේරීමකි. ඔබට ශුන්‍ය ආරක්ෂාව අවශ්‍ය නම් (ඔබ ශුන්‍ය භාවිතය අවම කිරීම සඳහා ලියා නැති කේත පදනමක් මත වැඩ කරන නිසා), අපාචේ වස්තු උපයෝගීතා හෝ ගුවාගේ වස්තු # සමාන (හෝ ඔබට ඔබේම රෝල් කළ හැකිය). කවුරුහරි ඩොනල්ඩ් නුත් පොතක් මට නිවැරදිව පහර දෙයි යන බියෙන් මම “කාර්ය සාධනය” යන වචනය සඳහන් නොකරමි.
laszlok

1117

හැකි ==මත භාවිතා කල enum?

ඔව්: සිද්ධි ==සංසන්දනය කිරීම සඳහා භාවිතා කිරීමට ඉඩ සලසන තද නිදර්ශන පාලක එනූම්ස් සතුව ඇත . භාෂා පිරිවිතරයෙන් සපයන සහතිකය මෙන්න (මා අවධාරණය කිරීම):

JLS 8.9 එනූම්ස්

එනූම් වර්ගයට එහි එනුම් නියතයන් මගින් අර්ථ දක්වා ඇති අවස්ථා හැර වෙනත් අවස්ථා නොමැත.

එනූම් වර්ගයක් පැහැදිලිව ක්ෂණිකව තහවුරු කිරීමට උත්සාහ කිරීම සම්පාදක කාල දෝෂයකි. මෙම final cloneපාලන ක්රමය Enumබව සහතික enumනියත කවදාවත් කරගත යුතු වේ, හා අනු අවස්ථා කවදාවත් deserialization ප්රතිඵලයක් ලෙස නිර්මාණය වී ඇති serialization යාන්ත්රණයක් බවටද සහතික විසින් විශේෂ ප්රතිකාර ලබා ඇත. එනූම් වර්ග පරාවර්තකව ස්ථාපනය කිරීම තහනම්ය. මෙම කරුණු හතරම එක්ව නියතයන් enumවිසින් නිර්වචනය කර ඇති ප්‍රමාණය ඉක්මවා කිසිදු ආකාරයක අවස්ථාවක් නොපවතින බව සහතික කරයි enum.

එක් එක් උදාහරණයක් පමණක් ඇති නිසා enumනියතය එය භාවිතා කිරීමට අවසර නොදෙනු ==ඇති වෙනුවට ක්රියාකරු equalsක්රමය එය ඔවුන් අවම වශයෙන් එක් වූ අදහස් කළ බව කවුරුත් හොඳින් දන්නා කාරණයකි නම් වස්තුව පද දෙකක් සාපේක්ෂව enumනියත . ( equalsක්‍රමවේදය Enumයනු finalහුදෙක් super.equalsඑහි තර්කයට ආයාචනා කර ප්‍රති result ලය ලබා දෙන අතර එමඟින් අනන්‍යතා සංසන්දනයක් සිදු කරයි.)

මෙම සහතිකය ජොෂ් බ්ලොච් නිර්දේශ කරන තරමට ශක්තිමත් වන අතර, ඔබ සිංගල්ටන් රටාව භාවිතා කිරීමට බල කරන්නේ නම්, එය ක්‍රියාත්මක කිරීමට ඇති හොඳම ක්‍රමය තනි මූලද්‍රව්‍යයක් භාවිතා කිරීමයි enum(බලන්න: Java ලදායී ජාවා 2 වන සංස්කරණය, අයිතමය 3: සිංගල්ටන් දේපල a සමඟ බලාත්මක කරන්න පුද්ගලික ඉදිකිරීම්කරු හෝ එනුම් වර්ගයක් ; සිංගල්ටන් හි නූල් ආරක්ෂාව )


==සහ අතර ඇති වෙනස්කම් equalsමොනවාද?

මතක් කිරීමක් ලෙස, එය සාමාන්‍යයෙන් ==ශක්‍ය විකල්පයක් නොවන බව පැවසිය යුතුය equals. කෙසේ වෙතත්, (සමඟ වැනි enum) සලකා බැලිය යුතු වැදගත් වෙනස්කම් දෙකක් තිබේ:

== කවදාවත් විසි කරන්නේ නැහැ NullPointerException

enum Color { BLACK, WHITE };

Color nothing = null;
if (nothing == Color.BLACK);      // runs fine
if (nothing.equals(Color.BLACK)); // throws NullPointerException

== සම්පාදනය කරන වේලාවේදී අනුකූලතා පරීක්ෂාවට යටත් වේ

enum Color { BLACK, WHITE };
enum Chiral { LEFT, RIGHT };

if (Color.BLACK.equals(Chiral.LEFT)); // compiles fine
if (Color.BLACK == Chiral.LEFT);      // DOESN'T COMPILE!!! Incompatible types!

==අදාළ වන විට භාවිතා කළ යුතුද ?

ඔවුන්ගේ අවස්ථා පිළිබඳ නිසි පාලනයක් ඇති වෙනස් කළ නොහැකි පංති ==භාවිතා කළ හැකි තම සේවාදායකයින්ට සහතික කළ හැකි බව බ්ලොච් විශේෂයෙන් සඳහන් කරයි . enumනිදර්ශනය කිරීම සඳහා විශේෂයෙන් සඳහන් කර ඇත.

අයිතමය 1: ඉදිකිරීම්කරුවන් වෙනුවට ස්ථිතික කර්මාන්තශාලා ක්‍රම සලකා බලන්න

[...] එය සමාන අවස්ථා දෙකක් නොපවතින බවට සහතිකයක් ලබා දීමට වෙනස් කළ නොහැකි පන්තියකට ඉඩ දෙයි: a.equals(b)තිබේ නම් සහ එසේ නම් පමණි a==b. පංතියක් මෙම සහතිකය ලබා දෙන්නේ නම්, එහි සේවාදායකයින්ට ක්‍රමවේදය ==වෙනුවට ක්‍රියාකරු භාවිතා කළ හැකි equals(Object)අතර එමඟින් කාර්ය සාධනය වැඩි දියුණු විය හැකිය. එනුම් වර්ග මෙම සහතිකය සපයයි.

සාරාංශගත කිරීම සඳහා, භාවිතා ==කිරීම සඳහා වන තර්ක enum:

  • එය වැඩ කරනවා.
  • එය වේගවත් ය.
  • ධාවන වේලාවේදී එය ආරක්ෂිතයි.
  • සම්පාදනය කරන වේලාවේදී එය ආරක්ෂිතයි.

28
ලස්සන පිළිතුර නමුත් ... 1. ඒක වැඩ : එකඟ 2. ඒ වඩා වේගවත් : enums සඳහා එය ඔප්පු :) 3. එය ලකුණු අවස්ථාවේ දී ආරක්ෂිත වේ : Color nothing = null;IMHO දෝෂය හා ස්ථාවර කළ යුතු අතර, ඔබගේ නිඛිල වටිනාකම් දෙකක් ඇත, තුනක් නැත ( ටොම් හෝවින්ගේ අදහස බලන්න) 4. සම්පාදනය කරන වේලාවේදී එය ආරක්ෂිතයි : හරි, නමුත් equalsතවමත් නැවත පැමිණේ false. අවසානයේදී, මම එය මිලදී ගන්නේ නැත, equals()කියවීමේ හැකියාව සඳහා මම කැමැත්තෙමි (කෙවින්ගේ අදහස බලන්න).
පැස්කල් තිවෙන්ට්

203
සමහර අයට foo.equals(bar)වඩා එය කියවිය හැකි යැයි සිතන foo == bar
ජාවාට

19
එය ක්‍රියාත්මක වේ: ප්‍රතිනිර්මාණය කිරීමේ කොටසක් ලෙස ඔබට පන්තියක් ආදේශ කිරීමට අවශ්‍ය වන තෙක්. == භාවිතා කරමින් සියලු කේත සොයා ගැනීම වාසනාවකි. එය වේගවත් ය: සත්‍ය වුවද (සැක සහිත), නොට් නොමේරූ ප්‍රශස්තිකරණය පිළිබඳ උපුටා දැක්වීමක් තිබේ. ධාවන වේලාවේදී ආරක්ෂිතයි: NullPointerException වෙතින් ඔබව වෙන් කරන එකම දෙය == භාවිතා කිරීම නම් මතකයට නැඟෙන පළමු වචනය "ආරක්ෂිත" නොවේ. සම්පාදනය කරන වේලාවේදී ආරක්ෂිතයි: ඇත්ත වශයෙන්ම නොවේ. වැරදි වර්ග සංසන්දනය කිරීමේ මූලික වැරැද්දෙන් එය ඔබව ආරක්ෂා කළ හැකිය, නමුත් නැවතත්, ඔබේ ක්‍රමලේඛකයින් කෙතරම් ගොළු නම්, “ආරක්ෂිත” යනු ඔබ නොවන එක දෙයකි.
laszlok

35
"ඔබේ ක්‍රමලේඛකයින් කෙතරම් ගොළු නම්," ආරක්ෂිත "යනු ඔබ නොවන එකම දෙයයි." - මම මෙම උපුටා දැක්වීමට එකඟ නොවෙමි. කේතය ක්‍රියාත්මක වීමට පෙර පවා, සම්පාදනය කරන වේලාවේදී "ගොළු" වැරදි වළක්වා ගැනීම යනු කුමක්ද? බුද්ධිමත් අය පවා ගොළු වැරදි කරති, පොරොන්දු වලට වඩා සමහර සහතික කිරීම් හොඳයි.
ymajoros

7
@laszlok: විශ්වාසයි, නමුත් දේවල් අසාර්ථක විය හැකි නම්, ඒවා සිදුවනු ඇත. සමහර ගොළු වැරදි සඳහා වැටක් තිබීම සැමවිටම හොඳ දෙයකි. අඩු සුළු දෝෂ සඳහා නිර්මාණශීලී වීමට ඕනෑ තරම් ඉඩ තිබේ, ඔබේ කේතය ක්‍රියාත්මක කිරීමට උත්සාහ කිරීමට පෙර සම්පාදකයාට මෙය හැසිරවීමට ඉඩ දෙන්න.
ymajoros

90

==එක් එක් එනූම් නියතයට එක් වස්තුවක් පමණක් ඇති බැවින්, එනුම් අගයන් දෙකක් සංසන්දනය කිරීම භාවිතා කරයි.

පැති සටහනක, ඇත්ත වශයෙන්ම ==ඔබ මේ ආකාරයට ලියන්නේ නම්, ශුන්‍ය-ආරක්ෂිත කේත ලිවීමට භාවිතා කිරීමේ අවශ්‍යතාවයක් නොමැත equals():

public useEnums(final SomeEnum a) {
    if (SomeEnum.SOME_ENUM_VALUE.equals(a)) {
        
    }
    
}

මෙය ඔබ අනිවාර්යයෙන්ම අනුගමනය කළ යුතු වමේ සිට නියතයන් සංසන්දනය කිරීම ලෙස හැඳින්වෙන හොඳම භාවිතයකි .


9
.equals()නූල් අගයන් ඇතුළත් කිරීමේදී මම මෙය සිදු කරමි, නමුත් මම තවමත් සිතන්නේ එය ශුන්‍ය-ආරක්ෂිත කේතයක් ලිවීමට කපටි ක්‍රමයක් බවයි. මට බොහෝ විට ක්‍රියාකරුවෙකු (හෝ ක්‍රමයක් ඇත, නමුත් මම දනිමි [ශුන්‍ය වස්තුව] .සමහර ජාවා හි කිසි විටෙකත් ශුන්‍ය ආරක්ෂිත නොවනු ඇත. තිත් ක්‍රියාකරු ක්‍රියා කරන ආකාරය නිසා) එය නොසලකා සෑම විටම ශුන්‍ය ආරක්ෂිත වේ. එය භාවිතා කරන අනුපිළිවෙල. අර්ථාන්විතව, "සමාන" ක්‍රියාකරු සෑම විටම ගමන් කළ යුතුය .
මැට් බෝල්

2
හොඳයි, ජාවා හි ග්‍රෝවි ( ?.) හි ආරක්ෂිත සංචාලන ක්‍රියාකරු නොමැති බැවින්, නියතයන් හා සසඳන විට මම මෙම ක්‍රියාව දිගටම භාවිතා කරමි. ටී.බී.එච්, මට එය කපටි බවක් නොපෙනේ, සමහර විට අඩු “ස්වාභාවික” ය.
පැස්කල් තිවෙන්ට්

32
nullනිඛිල සාමාන්යයෙන් දෝෂයක් ඇත. ඔබට හැකි සෑම අගයක්ම ගණනය කර ඇති අතර මෙන්න තවත් එකක්!
ටොම් හෝවින් -

8
පැහැදිලිව විවරණය කර ඇති අගයන් හැරුණු විට @Nullable, වමේ සිට නියතයන් සංසන්දනය කිරීම ප්‍රති-රටාවක් ලෙස මම සලකන්නේ එය අගයන් ශුන්‍ය කළ හැකි හෝ කළ නොහැකි දේ පිළිබඳ අවිනිශ්චිතතාවයක් පතුරවන බැවිනි. එනූම් වර්ග කිසි විටෙකත් නොවිය යුතුය @Nullable, එබැවින් ශුන්‍ය අගයක් ක්‍රමලේඛන දෝෂයක් වනු ඇත; එවැනි අවස්ථාවකදී, ඔබ ඉක්මනින් එන්පීඊ විසි කරන තරමට, ඔබේ ක්‍රමලේඛන වැරැද්ද අහෝසි වීමට ඉඩ දුන් තැන ඔබ සොයා ගනු ඇත. එබැවින් "හොඳම පුහුණුව ... ඔබ අනිවාර්යයෙන්ම අනුගමනය කළ යුතුය" යන්න එනුම් වර්ග සම්බන්ධයෙන් ගත් විට පැහැදිලිවම වැරදිය.
ටොබියාස්

26
වමේ සිට නියතයන් සසඳා බලන්න යෝධ විලාසිතාවේ හොඳම පුහුණුව හොඳම ඉංග්‍රීසි වේ.
maaartinus

58

අනෙක් අය පවසා ඇති පරිදි, දෙකම ==සහ .equals()බොහෝ අවස්ථාවන්හි වැඩ කරයි. ඔබ වෙනත් අය විසින් පෙන්වා දී ඇති සම්පූර්ණයෙන්ම වෙනස් වස්තු සංසන්දනය නොකරන කාල නියමය වලංගු හා ප්‍රයෝජනවත් වේ, කෙසේ වෙතත් විවිධ සංයුක්ත කාල වර්ග දෙකක වස්තු සංසන්දනය කිරීමේ විශේෂිත දෝෂය ද FindBugs විසින් සොයා ගනු ඇත (සහ බොහෝ විට Eclipse / IntelliJ විසින් කාල පරීක්ෂාවන් සම්පාදනය කරයි), එබැවින් එය සොයා ගන්නා ජාවා සම්පාදකයාට එතරම් අමතර ආරක්ෂාවක් එක් නොවේ.

කෙසේවෙතත්:

  1. බව ==මගේ සිතේ NPE අවුලට කවදාවත් වේ අවාසිය පිළිබඳ ==. ඔබට enumවර්ග ප්‍රකාශ කිරීමේ අවශ්‍යතාවයක් කිසිසේත්ම තිබිය යුතු නැත null, මන්ද ඔබට ප්‍රකාශ කිරීමට අවශ්‍ය ඕනෑම අමතර තත්වයක් අතිරේක අවස්ථාවක් ලෙස nullඑකතු කළ හැකි බැවිනි enum. එය අනපේක්ෂිත ලෙස නම් null, නිහ ly ==ව අසත්‍යය තක්සේරු කරනවාට වඩා මට NPE එකක් තිබිය යුතුය . එබැවින් ධාවන කාල මතයට වඩා ආරක්ෂිත යැයි මම එකඟ නොවෙමි ; කිසි විටෙකත් enumසාරධර්මවලට ඉඩ නොදීමට පුරුද්දට පිවිසීම හොඳය @Nullable.
  2. ඇතැයි යන තර්කය ==වන්නේ වේගවත් ද ව්යාජ වේ. බොහෝ අවස්ථාවල දී ඔබ කතා කරන්නම් .equals()කාගේ බැදීමකට වර්ගය නිඛිල පන්තිය බවත්, එවැනි අවස්ථාවන්හිදී සම්පාදකවරයා මෙම සමාන බව දැන හැකි විචල්ය මත ==(බැවින් enumගේ equals()ක්රමය ඉක්මවනු විය හැක) මෙම උත්සවයට ඇමතුමක් උපරිම ඵල හැකි ඉවතට. සම්පාදකයා දැනට මෙය කරන්නේ දැයි මට විශ්වාස නැත, නමුත් එය එසේ නොවන්නේ නම් සහ සමස්තයක් වශයෙන් ජාවා හි කාර්ය සාධන ගැටලුවක් බවට පත්වේ නම්, ජාවා ක්‍රමලේඛකයින් 100,000 ක් ඔවුන්ගේ ක්‍රමලේඛන විලාසය ගැලපෙන පරිදි වෙනස් කරනවාට වඩා මම සම්පාදකය නිවැරදි කරමි. විශේෂිත සම්පාදක අනුවාදයක කාර්ය සාධන ලක්ෂණ.
  3. enumsවස්තු වේ. අනෙක් සියලුම වස්තු වර්ග සඳහා සම්මත සංසන්දනය .equals()නොවේ ==. ව්‍යතිරේකයක් කිරීම භයානක යැයි මම සිතන්නේ enumsඔබ ==ඒ වෙනුවට අහම්බෙන් වස්තු සංසන්දනය කිරීම නිසා විය හැකිය equals(), විශේෂයෙන් ඔබ එනුම් enumනොවන පන්තියකට ප්‍රතිනිර්මාණය කරන්නේ නම් . එවැනි ප්‍රතිචක්‍රීකරණයකදී, එය ඉහළින් ක්‍රියාත්මක වන ස්ථානය වැරදිය. භාවිතයක් ==නිවැරදි බව ඔබට ඒත්තු ගැන්වීමට , ප්‍රශ්නයේ වටිනාකම enumප්‍රාථමිකද නැතිනම් ප්‍රාථමිකද යන්න පරීක්ෂා කර බැලිය යුතුය ; එය enumපංතියක් නොවන නම් , එය වැරදියි, නමුත් එය මඟ හැරීම පහසුය, මන්ද කේතය තවමත් සම්පාදනය වනු ඇත. භාවිතා කරන විට ඇති එකම අවස්ථාව.equals()වැරදියි යනු ප්‍රශ්නයේ අගයන් ප්‍රාථමික නම්; එවැනි අවස්ථාවකදී, කේතය සම්පාදනය නොවන බැවින් එය මග හැරීමට වඩා අපහසු වේ. එබැවින් .equals()නිවැරදි යැයි හඳුනා ගැනීම වඩා පහසු වන අතර අනාගත ප්‍රතිචක්‍රීකරණයන්ට එරෙහිව එය ආරක්ෂිත වේ.

මම ඇත්ත වශයෙන්ම සිතන්නේ ජාවා භාෂාව වම් අතෙහි අගය මත .equals () ඇමතීමට සහ වස්තු අනන්‍යතාවය සඳහා වෙනම ක්‍රියාකරුවෙකු හඳුන්වා දීමට වස්තු මත අර්ථ දැක්විය යුතු නමුත් ජාවා අර්ථ දක්වා ඇත්තේ එලෙස නොවේ.

සාරාංශයක් ලෙස, මම තවමත් සිතන්නේ තර්ක වර්ග .equals()සඳහා භාවිතා කිරීමට පක්ෂව සිටින enumබවයි.


4
හොඳයි, 3 වන කරුණ ගැන, මට ඉලක්කයක් enumලෙස භාවිතා කළ හැකි switchනිසා ඒවා ටිකක් විශේෂයි. Strings ද ටිකක් විශේෂයි.
CurtainDog

ස්විච් ප්‍රකාශ සඳහා වන වාක්‍ය ඛණ්ඩයේ == හෝ .equals () අඩංගු නොවේ, එබැවින් ඔබේ අදහස කුමක්දැයි මට නොපෙනේ. මගේ කරුණ 3.) යනු පා code කයෙකුට සත්‍යාපනය කිරීම කොතරම් පහසු කේතයක් ද යන්නයි. ස්විච් ප්‍රකාශය සම්පාදනය කරන තාක් කල් ස්විච් ප්‍රකාශවල සමානාත්මතා අර්ථ නිරූපණය නිවැරදි වේ.
ටොබියාස්

17

මම ==ඒ වෙනුවට භාවිතා කිරීමට කැමැත්තෙමි equals:

වෙනත් හේතුවක් නම්, මෙහි දැනටමත් සාකච්ඡා කර ඇති අනෙක් ඒවාට අමතරව, ඔබට එය නොදැන දෝෂයක් හඳුන්වා දිය හැකිද? ඔබට මෙම එනූම්ස් හරියටම සමාන නමුත් වෙන්වූ පැකේජ වල තිබේ යැයි සිතමු (එය පොදු නොවේ, නමුත් එය සිදුවිය හැකිය):

පළමු enum :

package first.pckg

public enum Category {
    JAZZ,
    ROCK,
    POP,
    POP_ROCK
}

දෙවන enum:

package second.pckg

public enum Category {
    JAZZ,
    ROCK,
    POP,
    POP_ROCK
}

එවිට ඔබ තුළ මෙන් තැනෙන්නේ භාවිතා සිතමු item.categoryවන first.pckg.Categoryනමුත්, ඔබ දෙවන නිඛිල (ආනයනය second.pckg.Categoryඑය සාක්ෂාත් නොමැතිව පළමු වෙනුවට):

import second.pckg.Category;
...

Category.JAZZ.equals(item.getCategory())

ඒ නිසා ඔබට falseසත්‍යය අපේක්ෂා කළත් ඔබට ලැබිය යුතු දේ වෙනස් item.getCategory()වේ JAZZ. එය බැලීමට ටිකක් අපහසු විය හැකිය.

එබැවින්, ඔබ ඒ වෙනුවට ක්‍රියාකරු භාවිතා කරන්නේ නම් ඔබට ==සම්පාදක දෝෂයක් ඇත:

operator == "second.pckg.Category", "first.pckg.Category" වෙත යෙදිය නොහැක.

import second.pckg.Category; 
...

Category.JAZZ == item.getCategory() 

ඔබ සඳහන් කළ ඉතා හොඳ කරුණු. ඉතින් මම කරන්නෙ myenum.value () යෙදීම සහ NPE ආරක්ෂාව සඳහා == සංසන්දනය කිරීමයි.
ජාවා ප්‍රධාන

14

මේ දෙක සංසන්දනය කිරීම සඳහා ගොරහැඩි කාල පරීක්ෂණයක් මෙන්න:

import java.util.Date;

public class EnumCompareSpeedTest {

    static enum TestEnum {ONE, TWO, THREE }

    public static void main(String [] args) {

        Date before = new Date();
        int c = 0;

        for(int y=0;y<5;++y) {
            for(int x=0;x<Integer.MAX_VALUE;++x) {
                if(TestEnum.ONE.equals(TestEnum.TWO)) {++c;}
                if(TestEnum.ONE == TestEnum.TWO){++c;}              
            }
        }

        System.out.println(new Date().getTime() - before.getTime());
    }   

}

වරකට IFs ගැන අදහස් දක්වන්න. විසුරුවා හරින ලද බයිට් කේතයෙන් ඉහළින් සැසඳීම් දෙක මෙන්න:

 21  getstatic EnumCompareSpeedTest$TestEnum.ONE : EnumCompareSpeedTest.TestEnum [19]
 24  getstatic EnumCompareSpeedTest$TestEnum.TWO : EnumCompareSpeedTest.TestEnum [25]
 27  invokevirtual EnumCompareSpeedTest$TestEnum.equals(java.lang.Object) : boolean [28]
 30  ifeq 36

 36  getstatic EnumCompareSpeedTest$TestEnum.ONE : EnumCompareSpeedTest.TestEnum [19]
 39  getstatic EnumCompareSpeedTest$TestEnum.TWO : EnumCompareSpeedTest.TestEnum [25]
 42  if_acmpne 48

පළමු (සමාන) අථත්‍ය ඇමතුමක් සිදු කරන අතර තොගයේ සිට ආපසු එන බූලියන් පරීක්ෂා කරයි. දෙවැන්න (==) වස්තු ලිපින සෘජුවම තොගයෙන් සංසන්දනය කරයි. පළමු අවස්ථාවේ දී වැඩි ක්රියාකාරිත්වයක් ඇත.

මම එකවරම IFs දෙකම සමඟ මෙම පරීක්ෂණය කිහිප වතාවක්ම ධාවනය කළෙමි. "==" සෑම විටම තරමක් වේගවත් වේ.


සම්පාදක ශාඛා පුරෝකථනය මෙම පරීක්ෂණය අවලංගු කරයි යැයි මම සැක කරමි. ස්මාර්ට් සම්පාදකයෙකු විසින් ප්‍රකාශයන් සෑම විටම අසත්‍ය ලෙස තක්සේරු කරනු ඇති අතර එමඟින් බහු සැසඳීම් කිරීමෙන් වැළකී සිටින බව හඳුනා ගනී. සැබවින්ම ස්මාර්ට් සම්පාදකයෙකු විසින් y සහ x ලූපවල අගයන් ප්‍රති come ලයට කිසිදු බලපෑමක් නොකරන බව හඳුනාගෙන මුළු දේම ප්‍රශස්ත කරයි ...
ඩැරල් හොෆ්මන්

එය කළ හැකි නමුත් එය අනිවාර්යයෙන්ම නැත. මගේ පිළිතුරෙහි සත්‍ය සම්පාදක ජනනය කළ බයිට් කේතය පෙන්වයි.
ක්‍රිස්කාන්ට්‍රෙල්

ඔබ දෙදෙනාම ව්‍යාකූලයි. :-) ශාඛා පුරෝකථනය ක්‍රියාත්මක වන වේලාවේදී ක්‍රියාත්මක වන බැවින් විවිධ බයිට් කේතය සුපිරි අදාළ නොවේ. කෙසේ වෙතත්, මෙම අවස්ථාවේ දී ශාඛා පුරෝකථනය අවස්ථා දෙකම එක හා සමානව උපකාරී වේ.
vidstige

7
කව්ද ගනන් ගන්නේ? වීඩියෝ ක්‍රීඩාවකදී ඔබ ලූපයක් තුළ දහස් වාරයක් සංසන්දනය නොකරන්නේ නම් අමතර නැනෝ තත්පරයට තේරුමක් නැත.
user949300

ඔබ අර්ථකථන මාදිලියට බල නොකරන්නේ නම් බයිට් කේතය කාර්ය සාධනය සඳහා බෙහෙවින් අදාළ නොවේ. කාර්ය සාධනය හරියටම සමාන බව බැලීමට JMH මිණුම් ලකුණක් ලියන්න .
maaartinus


7

tl; dr

තවත් විකල්පයක් වන්නේ Objects.equalsඋපයෝගිතා ක්‍රමයයි.

Objects.equals( thisEnum , thatEnum )

Objects.equals ශුන්‍ය ආරක්ෂාව සඳහා

.equals () වෙනුවට ක්‍රියාකරු == සමාන වේ

මා භාවිතා කළ යුත්තේ කුමන ක්‍රියාකරුද?

තෙවන විකල්පය වන්නේ ජාවා 7 සහ ඊට පසුව එකතුequals කරන ලද Objectsඋපයෝගිතා පන්තියේ ස්ථිතික ක්‍රමයයි .

උදාහරණයක්

මෙන්න Monthenum භාවිතා කරන උදාහරණයක් .

boolean areEqual = Objects.equals( Month.FEBRUARY , Month.JUNE ) ;  // Returns `false`.

ප්‍රතිලාභ

මෙම ක්‍රමයට ප්‍රතිලාභ කිහිපයක් මම සොයා ගතිමි:

  • ශුන්‍ය ආරක්ෂාව
    • දෙකම ශුන්‍ය true
    • එක්කෝ ශුන්‍ය false
    • විසි කිරීමේ අවදානමක් නැත NullPointerException
  • සංයුක්ත, කියවිය හැකි

එය ක්‍රියාත්මක වන ආකාරය

භාවිතා කරන තර්කනය Objects.equalsකුමක්ද?

සිට, ඔබම බලන්න ජාවා 10 මූල කේතය පිළිබඳ OpenJDK :

return (a == b) || (a != null && a.equals(b));

6

==එනුම් නියතයන් සංසන්දනය කිරීම හැර වෙනත් දෙයක් භාවිතා කිරීම විකාරයකි. එය වස්තූන් සමඟ සංසන්දනය කිරීමක්classequals වැනිය - එය නොකරන්න!

කෙසේ වෙතත්, සන් ජේඩීකේ 6u10 සහ ඊට පෙර අප්රසන්න දෝෂයක් (බග් අයිඩ් 6277781 ) ඇති අතර එය මීට පෙර historical තිහාසික හේතූන් මත සිත්ගන්නා සුළු විය හැකිය. මෙම දෝෂය නිසා ==ඩෙසරීකරණය කළ එනූම් නිසි ලෙස භාවිතා කිරීම වලක්වනු ලැබීය .


4

එනුම් යනු පංති යනු එක් එක් ගණන් කිරීමේ නියතය සඳහා (නිශ්චල නොවන) ප්‍රකාශිත එක් අවස්ථාවක් (සිංගල්ටන් වැනි) ලබා දෙන අතර public static final fieldඑමඟින් ක්‍රමවේදය ==භාවිතා කරනවාට වඩා ඔවුන්ගේ සමානාත්මතාවය පරීක්ෂා කිරීමට ක්‍රියාකරුට හැකි equals()වේ.


1

Enums == සමඟ පහසුවෙන් ක්‍රියා කිරීමට හේතුව වන්නේ එක් එක් නිර්වචනය කළ අවස්ථාව ද තනි පුද්ගලයෙකි. එබැවින් == භාවිතා කරමින් අනන්‍යතා සංසන්දනය සැමවිටම ක්‍රියාත්මක වේ.

නමුත් == භාවිතා කිරීම එය එනූම්ස් සමඟ ක්‍රියා කරන නිසා ඔබේ කේත සියල්ලම එම එනූම් භාවිතය සමඟ තදින් බැඳී ඇත.

උදාහරණයක් ලෙස: එනූම්ස් හට අතුරු මුහුණතක් ක්‍රියාත්මක කළ හැකිය. ඔබ දැනට භාවිතා කරන්නේ ඉන්ටර්ෆේස් 1 ක්‍රියාත්මක කරන එනූම් එකක් යැයි සිතමු. පසුකාලීනව, යමෙකු එය වෙනස් කිරීම හෝ එකම අතුරු මුහුණතක් ක්‍රියාත්මක කිරීමක් ලෙස නව පන්තියේ Impl1 හඳුන්වා දෙයි. ඉන්පසුව, ඔබ Impl1 හි නිදසුන් භාවිතා කිරීමට පටන් ගන්නේ නම්, පෙර භාවිතා කළ == නිසා වෙනස් කිරීමට සහ පරීක්ෂා කිරීමට ඔබට කේත රාශියක් ඇත.

එබැවින් සාධාරණ ප්‍රතිලාභයක් නොමැති නම් හොඳ පුරුද්දක් ලෙස සලකන දේ අනුගමනය කිරීම වඩාත් සුදුසුය.


හොඳ පිළිතුරක්, නමුත් දැනටමත් මෙහි සඳහන් කර ඇත .
shmosel

ම්ම්. එම අවස්ථාවේදී, ප්‍රශ්නය වනුයේ ඔබ == භාවිතා කරනවාද නැතිනම් අතුරු මුහුණතක සමානද යන්නයි. වෙනස් කළ නොහැකි වර්ගයක් ක්‍රියාත්මක කිරීම විකෘති ක්‍රියාවට නැංවීම වෙනුවට එය සැබවින්ම සංවේදීද යන්න පිළිබඳ සියලු ආකාරයේ ප්‍රශ්න. සාධාරණ වාසි ගැන කරදර වීමට පෙර හොඳ පුරුද්ද කුමක්දැයි සොයා බැලීම නුවණට හුරුය. (imho == වඩා හොඳ පුහුණුවකි).
රොබින් ඩේවිස්

1

සෝනාර් නීති වලින් එකක් Enum values should be compared with "==". හේතු පහත පරිදි වේ:

equals()එනමූම් වස්තුවක් වන නිසාත්, සෑම ජාවා සංවර්ධකයෙකුම දන්නා වස්තුවක ==අන්තර්ගතය සංසන්දනය කිරීම සඳහා භාවිතා නොකළ යුතු නිසාත්, එනුම් අගය සමඟ සමානාත්මතාවය පරීක්ෂා කිරීම පරිපූර්ණ ලෙස වලංගු වේ . ඒ සමගම, ==enums භාවිතා කිරීම:

  • අපේක්ෂිත සංසන්දනය (අන්තර්ගතය) සපයයි equals()

  • වඩා ශුන්‍ය-ආරක්ෂිතයි equals()

  • ධාවන කාල පරීක්ෂාවට වඩා සම්පාදක-කාල (ස්ථිතික) පරීක්ෂාව සපයයි

මෙම හේතු නිසා, භාවිතය ==වඩාත් කැමති විය යුතුය equals().

අවසාන වශයෙන් නොව, ==එනූම්ස් මත වාදයට වඩා කියවිය හැකි (අඩු වාචික) equals().


0

කෙටියෙන් කිවහොත්, දෙදෙනාම වාසි සහ අවාසි ඇත.

එක් අතකින්, ==අනෙක් පිළිතුරු වල විස්තර කර ඇති පරිදි එය භාවිතා කිරීමට වාසි ඇත .

අනෙක් අතට, ඔබ කිසියම් හේතුවක් නිසා එනූම්ස් වෙනුවට වෙනත් ප්‍රවේශයකින් (සාමාන්‍ය පන්ති අවස්ථා) ආදේශ කරන්නේ නම්, ඔබ ==දෂ්ට කරයි. (BTDT.)


-1

මට බහු අවයවික පිළිතුරු සම්පුර්ණ කිරීමට අවශ්‍යයි:

මම පෞද්ගලිකව සමාන () වලට කැමතියි. නමුත් එය වර්ගයේ ගැළපුම පරීක්ෂා කරයි. එය වැදගත් සීමාවක් යැයි මම සිතමි.

සම්පාදනය කරන වේලාවේදී වර්ගීකරණ අනුකූලතා පරීක්‍ෂණයක් කිරීමට, ඔබේ එනූම් හි අභිරුචි ශ්‍රිතයක් ප්‍රකාශ කර භාවිතා කරන්න.

public boolean isEquals(enumVariable) // compare constant from left
public static boolean areEqual(enumVariable, enumVariable2) // compare two variable

මේ සමඟ, ඔබට විසඳුම් දෙකේම සියලු වාසි ලැබුණි: එන්පීඊ ආරක්ෂාව, කේත කියවීමට පහසු සහ සම්පාදක වේලාවේදී අනුකූලතා පරීක්ෂාව ටයිප් කරන්න.

එනුම් සඳහා නිර්වචනය නොකළ අගයක් එක් කිරීමට ද මම නිර්දේශ කරමි.


4
මෙම විසඳුම වඩා හොඳ වන්නේ ඇයි ==? ==ඔබට NPE ආරක්ෂාව, කියවීමට පහසු කේතයක් සහ කාල වර්ගයේ අනුකූලතා පරීක්‍ෂණයක් ලබා ගැනීමත් සමඟ, ඔබට අභිරුචි සමාන-සමාන ක්‍රම ලිවීමකින් තොරව
මැට් බෝල්

1
UNDEFINEDඅගය බොහෝ විට හොඳ අදහසක් වේ. ඇත්ත වශයෙන්ම, ජාවා 8 හි ඔබ ඒ Optionalවෙනුවට භාවිතා කරනු ඇත.
ටොමාස්
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.