ความคิดเห็นของฉันอาจขัดแย้ง แต่ใช่ฉันคิดว่ามีบางสถานการณ์ที่ฉันจะใช้รูปแบบนี้อย่างแน่นอน อย่างไรก็ตาม "เพียงเพื่อลดขอบเขตของตัวแปร" ไม่ใช่อาร์กิวเมนต์ที่ถูกต้องเพราะนั่นคือสิ่งที่คุณทำอยู่แล้ว และการทำสิ่งที่ต้องทำไม่ใช่เหตุผลที่ถูกต้อง โปรดทราบด้วยว่าคำอธิบายนี้ไม่มีความหมายว่าทีมของคุณได้รับการแก้ไขแล้วว่าไวยากรณ์ชนิดนี้เป็นแบบแผนหรือไม่
ฉันเป็นโปรแกรมเมอร์ C # เป็นหลัก แต่ฉันได้ยินมาว่าใน Java ให้ส่งคืนรหัสผ่านตามchar[]
ที่อนุญาตให้คุณลดเวลาที่รหัสผ่านจะยังคงอยู่ในหน่วยความจำ ในตัวอย่างนี้จะไม่ช่วยเพราะตัวเก็บรวบรวมขยะได้รับอนุญาตให้รวบรวมอาร์เรย์จากช่วงเวลาที่ไม่ได้ใช้งานดังนั้นจึงไม่จำเป็นว่ารหัสผ่านจะออกจากขอบเขตหรือไม่ ฉันไม่ได้โต้เถียงว่าเป็นไปได้หรือไม่ที่จะล้างอาเรย์หลังจากคุณทำเสร็จแล้ว แต่ในกรณีนี้ถ้าคุณต้องการทำมันการกำหนดขอบเขตให้เหมาะสม:
{
char[] password = getPassword();
try{
keyStore.load(new FileInputStream(keyStoreLocation), password);
keyManager.init(keyStore, password);
}finally{
Arrays.fill(password, '\0');
}
}
นี่คล้ายกับคำสั่งtry-with-resourcesจริงๆเพราะมันเป็นขอบเขตของทรัพยากรและทำการสรุปให้เสร็จสิ้นหลังจากที่คุณทำเสร็จแล้ว โปรดทราบอีกครั้งว่าฉันไม่ได้โต้เถียงกับการจัดการรหัสผ่านในลักษณะนี้เพียงว่าถ้าคุณตัดสินใจที่จะทำเช่นนั้นสไตล์นี้ก็สมเหตุสมผล
เหตุผลนี้เป็นเพราะตัวแปรไม่ถูกต้องอีกต่อไป คุณได้สร้างใช้งานและทำให้สถานะใช้งานไม่ได้เพื่อให้ไม่มีข้อมูลที่มีความหมาย ไม่เหมาะสมที่จะใช้ตัวแปรหลังจากบล็อกนี้ดังนั้นจึงเหมาะสมที่จะกำหนดขอบเขต
อีกตัวอย่างหนึ่งที่ฉันนึกได้ก็คือเมื่อคุณมีตัวแปรสองตัวที่มีชื่อและความหมายคล้ายกัน แต่คุณทำงานกับตัวแปรหนึ่งแล้วใช้กับตัวแปรอื่นและคุณต้องการแยกมันออกจากกัน ฉันได้เขียนรหัสนี้ใน C #:
{
MethodBuilder m_ToString = tb.DefineMethod("ToString", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, typeofString, Type.EmptyTypes);
var il = m_ToString.GetILGenerator();
il.Emit(OpCodes.Ldstr, templateType.ToString()+":"+staticType.ToString());
il.Emit(OpCodes.Ret);
tb.DefineMethodOverride(m_ToString, m_Object_ToString);
}
{
PropertyBuilder p_Class = tb.DefineProperty("Class", PropertyAttributes.None, typeofType, Type.EmptyTypes);
MethodBuilder m_get_Class = tb.DefineMethod("get_Class", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, typeofType, Type.EmptyTypes);
var il = m_get_Class.GetILGenerator();
il.Emit(OpCodes.Ldtoken, staticType);
il.Emit(OpCodes.Call, m_Type_GetTypeFromHandle);
il.Emit(OpCodes.Ret);
p_Class.SetGetMethod(m_get_Class);
tb.DefineMethodOverride(m_get_Class, m_IPattern_get_Class);
}
คุณสามารถยืนยันว่าฉันสามารถประกาศILGenerator il;
ที่ด้านบนของวิธีการ แต่ฉันก็ไม่ต้องการที่จะใช้ตัวแปรสำหรับวัตถุที่แตกต่างกัน (kinda functional approach) ในกรณีนี้บล็อกทำให้ง่ายต่อการแยกงานที่จะดำเนินการทั้ง syntactically และสายตา นอกจากนี้ยังบอกว่าหลังจากบล็อกฉันเสร็จแล้วil
และไม่มีอะไรควรเข้าถึง
การโต้แย้งกับตัวอย่างนี้ใช้วิธีการ อาจจะใช่ แต่ในกรณีนี้รหัสนั้นไม่นานและการแยกออกเป็นวิธีการต่าง ๆ ก็จะต้องผ่านตัวแปรทั้งหมดที่ใช้ในรหัส