คุณกำหนดตัวแปร Global ใน Java ได้อย่างไร?
คุณกำหนดตัวแปร Global ใน Java ได้อย่างไร?
คำตอบ:
เพื่อกำหนดตัวแปรส่วนกลางคุณสามารถใช้ประโยชน์จากคำหลักคงที่
public class Example {
public static int a;
public static int b;
}
ตอนนี้คุณสามารถเข้าถึง a และ b ได้จากทุกที่โดยการโทร
Example.a;
Example.b;
staticคำหลักที่ทำให้ตัวแปรที่สามารถเข้าถึงได้ทั่วโลกในขณะที่ระดับของพวกเขาจะเต็มไป
Globalเป็นอย่างอื่น ( TestClass?) เพื่อไม่ให้คนอื่นรู้สึกว่ามีสิ่งนั้นเป็นGlobalคำหลัก Java ปลอดภัยกว่าดีกว่าขออภัย :)
คุณทำไม่ได้ นั่นคือจากการออกแบบ คุณไม่ควรทำแม้ว่าคุณจะทำได้
ที่ถูกกล่าวว่าคุณสามารถสร้างชุดของสมาชิกคงที่สาธารณะในชั้นเรียนชื่อ Globals
public class Globals {
public static int globalInt = 0;
///
}
แต่คุณไม่ควรทำ :) อย่างจริงจัง .. ไม่ทำ
อีกวิธีคือสร้างอินเทอร์เฟซแบบนี้:
public interface GlobalConstants
{
String name = "Chilly Billy";
String address = "10 Chicken head Lane";
}
คลาสใด ๆ ที่จำเป็นต้องใช้จะต้องใช้อินเตอร์เฟส:
public class GlobalImpl implements GlobalConstants
{
public GlobalImpl()
{
System.out.println(name);
}
}
คุณควรใช้การฉีดแบบพึ่งพา:
public class Globals {
public int a;
public int b;
}
public class UsesGlobals {
private final Globals globals;
public UsesGlobals(Globals globals) {
this.globals = globals;
}
}
มีคำตอบที่ดีมากมาย แต่ฉันต้องการยกตัวอย่างนี้เนื่องจากมันถือว่าเป็นวิธีที่เหมาะสมกว่าในการเข้าถึงตัวแปรของคลาสโดยคลาสอื่นโดยใช้ getters และ setters
เหตุผลที่คุณใช้ getters และ setters ด้วยวิธีนี้แทนที่จะทำให้ตัวแปรสาธารณะเป็นดังนี้ ให้บอกว่า var ของคุณจะเป็นพารามิเตอร์ส่วนกลางที่คุณไม่ต้องการให้ใครบางคนเปลี่ยนแปลงระหว่างการทำงานของโปรแกรมของคุณ (ในกรณีที่คุณกำลังพัฒนาโค้ดกับทีม) สิ่งที่อาจเป็น URL สำหรับเว็บไซต์ ในทางทฤษฎีสิ่งนี้สามารถเปลี่ยนแปลงได้และอาจถูกใช้หลายครั้งในโปรแกรมของคุณดังนั้นคุณจึงต้องการใช้ var ส่วนกลางเพื่อให้สามารถอัปเดตได้ทั้งหมดในครั้งเดียว แต่คุณไม่ต้องการให้คนอื่นเข้ามาและเปลี่ยนแปลง var นี้ (อาจเป็นไปได้โดยไม่ทราบว่ามันสำคัญขนาดไหน) ในกรณีนั้นคุณไม่ต้องรวมเมธอด setter และรวมเฉพาะเมธอด getter เท่านั้น
public class Global{
private static int var = 5;
public static int getVar(){
return Global.var;
}
//If you do not want to change the var ever then do not include this
public static void setVar(int var){
Global.var = var;
}
}
ไม่มีตัวแปรโกลบอลใน Java
อย่างไรก็ตามสิ่งที่เรามีคือstaticคำหลักและนั่นคือทั้งหมดที่เราต้องการ ไม่มีสิ่งใดอยู่นอกคลาสใน Java staticคำหลักหมายถึงตัวแปรคลาสที่ตรงกันข้ามกับตัวแปรเช่นมีเพียงหนึ่งคัดลอกและฟันฝ่าว่าในทุกกรณีของชั้นเรียนที่สร้างขึ้นซึ่งหมายความว่าค่าของมันสามารถเปลี่ยนแปลงได้และเข้าถึงทั่วทุกกรณีที่จุดใด
หากคุณต้องการตัวแปรโกลบอลที่สามารถเข้าถึงได้นอกเหนือจากขอบเขตนี่คือตัวแปรที่คุณต้องการ แต่ขอบเขตนั้นมีอยู่เฉพาะที่คลาสนั้นและนั่นคือทั้งหมด
การพูดอย่างแท้จริงไม่มีแนวคิดของ"GLOBAL"ในโปรแกรม Java OO
อย่างไรก็ตามมีความจริงบางอย่างที่อยู่เบื้องหลังคำถามของคุณเพราะจะมีบางกรณีที่คุณต้องการใช้วิธีที่ส่วนใดส่วนหนึ่งของโปรแกรม ตัวอย่างเช่น --- random () วิธีการในแอป Phrase-O-Matic มันเป็นวิธีที่ควรจะเรียกจากทุกที่ของโปรแกรม
ดังนั้นเพื่อตอบสนองสิ่งต่าง ๆ ข้างบน "เราจำเป็นต้องมีตัวแปรและวิธีการเหมือนทั่วโลก"
เพื่อประกาศความหลากหลายทั่วโลก
1.Mark the variable as public static final While declaring.
จะประกาศวิธี AS GLOBAL
1. Mark the method as public static While declaring.
เนื่องจากฉันได้ประกาศตัวแปรและวิธีการแบบโกลบอลว่าเป็นแบบคงที่คุณสามารถเรียกมันได้ทุกที่ที่คุณต้องการเพียงแค่ใช้รหัสต่อไปนี้
ClassName.X
หมายเหตุ : X สามารถเป็นชื่อเมธอดหรือชื่อตัวแปรตามความต้องการและ ClassName เป็นชื่อของคลาสที่คุณประกาศ
ไม่มีอะไรควรเป็นระดับโลกยกเว้นค่าคงที่
public class MyMainClass {
public final static boolean DEBUGMODE=true;
}
ใส่สิ่งนี้ไว้ในชั้นเรียนหลักของคุณ ในไฟล์. java อื่น ๆ ให้ใช้ผ่าน:
if(MyMainClass.DEBUGMODE) System.out.println("Some debugging info");
ตรวจสอบให้แน่ใจว่าเมื่อคุณย้ายรหัสออกจากพื้นห้องตัดและปล่อยคุณลบหรือแสดงความคิดเห็นการทำงานนี้
หากคุณมีวิธี workhorse เช่น randomizer ผมแนะนำให้สร้างแพ็คเกจ "Toolbox"! โคเดอร์ทั้งหมดควรมีหนึ่งตัวจากนั้นเมื่อใดก็ตามที่คุณต้องการใช้ใน. java เพียงแค่นำเข้ามัน!
ไม่มีสิ่งนั้นเป็นตัวแปรระดับโลกอย่างแท้จริงใน Java ตัวแปรแบบคงที่ทุกตัวจะต้องเป็นของบางคลาส (เช่น System.out) แต่เมื่อคุณตัดสินใจว่าจะใช้คลาสใดในนั้นคุณสามารถอ้างอิงได้จากทุก ๆ โหลดโดย classloader เดียวกัน
โปรดทราบว่าตัวแปรคงที่ควรได้รับการปกป้องเมื่อทำการอัพเดตเพื่อหลีกเลี่ยงสภาพการแข่งขัน
public class GlobalClass {
public static int x = 37;
public static String s = "aaa";
}
วิธีนี้คุณสามารถเข้าถึงด้วยGlobalClass.xและGlobalClass.s
public class GlobalImpl {
public static int global = 5;
}
คุณสามารถโทรได้ทุกที่ที่คุณต้องการ:
GlobalImpl.global // 5
ในขณะที่คุณอาจเดาได้จากคำตอบไม่มีตัวแปรทั่วโลกใน Java และสิ่งเดียวที่คุณทำได้คือการสร้างคลาสที่มีสมาชิกแบบคงที่:
public class Global {
public static int a;
}
คุณสามารถใช้กับGlobal.aที่อื่น อย่างไรก็ตามถ้าคุณใช้ Java 1.5 หรือดีกว่าคุณสามารถใช้import staticเวทย์มนตร์เพื่อทำให้มันดูเป็นตัวแปรทั่วโลกได้มากขึ้น:
import static test.Global.*;
public class UseGlobal {
public void foo() {
int i = a;
}
}
และvoilà !
ตอนนี้มันยังห่างไกลจากแนวปฏิบัติที่ดีที่สุดอย่างที่คุณเห็นในโฆษณา: อย่าทำที่บ้าน
ไม่มีตัวแปรทั่วโลกใน Java แต่มีคลาสสากลที่มีเขตข้อมูลสาธารณะ คุณสามารถใช้คุณสมบัติการนำเข้าแบบคงที่ของ java 5 เพื่อทำให้มันดูเหมือนตัวแปรทั่วโลก
โดยทั่วไปแล้วตัวแปร Global (ฉันถือว่าคุณกำลังเปรียบเทียบกับ C, Cpp) กำหนดเป็น public static final
ชอบ
class GlobalConstant{
public static final String CODE = "cd";
}
ENUMs ยังมีประโยชน์ในสถานการณ์เช่นนี้:
ตัวอย่าง Calendar.JANUARY)
finalแต่ขึ้นอยู่กับวิธีที่คุณต้องการแบ่งปันที่คุณใช้และทุกอย่างแน่นอน
CODEนี้คืออะไร? มันกำหนดไว้ที่ไหน
การสร้างไฟล์อิสระเช่น ตัวอย่าง. java เพื่อใช้โซลูชันที่ 1 นั้นใช้ได้ คุณสามารถทำสิ่งนั้นได้ภายในแอพเช่นหากตัวแปรทั่วโลกเป็นพิเศษสำหรับแอปปัจจุบันของคุณ
สร้างคลาสที่จุดเริ่มต้นและประกาศตัวแปรของคุณในนั้น:
class Globals {
static int month_number;
static String month_name;
}
จากนั้นคุณสามารถเข้าถึงตัวแปรเหล่านี้ - ใช้พวกเขาเป็น 'Globals.month_number' ฯลฯ - จากทุกที่ในแอปของคุณ
ถ้าคุณต้องการอัพเดตคุณสมบัติโกลบอลคลาส wrapper getter / setter ที่เรียบง่ายสามารถใช้เป็นตัวแปรโกลบอล ตัวอย่างทั่วไปแสดงไว้ด้านล่าง
public class GlobalHolder {
private static final GlobalHolder INSTANCE = new GlobalHolder();
private volatile int globalProperty;
public static GlobalHolder getInstance() {
return INSTANCE;
}
public int getGlobalProperty() {
return globalProperty;
}
public void setGlobalProperty(int globalProperty) {
this.globalProperty = globalProperty;
}
public static void main(String[] args) {
GlobalHolder.getInstance().setGlobalProperty(10);
System.out.println(GlobalHolder.getInstance().getGlobalProperty());
}
}
ไปตามแนวคิดตัวแปรทั่วโลกหรือที่เรียกว่าตัวแปรอินสแตนซ์เป็นตัวแปรระดับชั้นกล่าวคือพวกเขาถูกกำหนดไว้ในชั้นเรียน แต่วิธีการนอก เพื่อให้สามารถใช้งานได้อย่างสมบูรณ์และใช้พวกเขาโดยตรงให้คำหลักคงที่ ดังนั้นหากฉันกำลังเขียนโปรแกรมสำหรับการดำเนินการเกี่ยวกับคณิตศาสตร์อย่างง่ายและมันต้องการคู่จำนวนแล้วตัวแปรอินสแตนซ์สองตัวจะถูกกำหนดดังนี้:
public class Add {
static int a;
static int b;
static int c;
public static void main(String arg[]) {
c=sum();
System.out.println("Sum is: "+c);
}
static int sum() {
a=20;
b=30;
return a+b;
}
}
Output: Sum is: 50
ยิ่งกว่านั้นการใช้คำสำคัญคงที่ก่อนตัวแปรอินสแตนซ์ทำให้เราไม่สามารถระบุประเภทข้อมูลสำหรับตัวแปรเดียวกันซ้ำแล้วซ้ำอีก เพียงเขียนตัวแปรโดยตรง
static'ไม่ทำให้พวกเขาพร้อมใช้งานอย่างสมบูรณ์' วรรคแรกไร้สาระ ตัวอย่างคือการปฏิบัติที่ไม่ดี
โดยทั่วไปแล้ว Java ไม่มีตัวแปรทั่วโลก นอกเหนือจากตัวแปรโลคัลตัวแปรทั้งหมดจะอยู่ภายใต้ขอบเขตของคลาสใด ๆ ที่กำหนดไว้ในโปรแกรม เราสามารถมีตัวแปรสแตติกที่จะมีขอบเขตของตัวแปรทั่วโลก
หากไม่มีstaticสิ่งนี้ก็เป็นไปได้เช่นกัน:
class Main {
String globalVar = "Global Value";
class Class1 {
Class1() {
System.out.println("Class1: "+globalVar);
globalVar += " - changed";
} }
class Class2 {
Class2() {
System.out.println("Class2: "+globalVar);
} }
public static void main(String[] args) {
Main m = new Main();
m.mainCode();
}
void mainCode() {
Class1 o1 = new Class1();
Class2 o2 = new Class2();
}
}
/*
Output:
Class1: Global Value
Class2: Global Value - changed
*/
การเขียนโปรแกรมเชิงวัตถุถูกสร้างขึ้นด้วยความเข้าใจว่าขอบเขตของตัวแปรนั้นมีความพิเศษอย่างใกล้ชิดกับวัตถุคลาสที่ห่อหุ้มตัวแปรเหล่านั้น
ปัญหาในการสร้าง "ตัวแปรทั่วโลก" คือไม่ใช่มาตรฐานอุตสาหกรรมสำหรับ Java ไม่ใช่มาตรฐานอุตสาหกรรมเนื่องจากอนุญาตให้หลายคลาสจัดการข้อมูลแบบอะซิงโครไนซ์ถ้าคุณใช้แอปพลิเคชันแบบมัลติเธรดสิ่งนี้จะซับซ้อนและเป็นอันตรายเล็กน้อยในแง่ของความปลอดภัยของเธรด มีเหตุผลอื่น ๆ อีกมากมายว่าทำไมการใช้ตัวแปรทั่วโลกจะไม่ได้ผล แต่ถ้าคุณต้องการที่จะหลีกเลี่ยงการที่ผมแนะนำให้คุณหันไปใช้การเขียนโปรแกรมเชิงลักษณะ
การเขียนโปรแกรมที่มุ่งเน้นเชิงลบล้างปัญหานี้โดยการใส่ชั้นผู้ปกครองในการดูแลขอบเขตผ่านสิ่งที่เรียกว่า "คำแนะนำ" ซึ่งเพิ่มพฤติกรรมเพิ่มเติมให้กับรหัสโดยไม่ต้องแก้ไขมันจริง มันนำเสนอโซลูชั่นเพื่อแก้ไขข้อกังวลข้ามหรือการใช้ตัวแปรทั่วโลก
Springเป็นเฟรมเวิร์ก Java ที่ใช้ AOP และในขณะที่มันถูกใช้แบบดั้งเดิมสำหรับเว็บแอ็พพลิเคชันแอปพลิเคชันหลักสามารถใช้ได้ทั่วทั้งกรอบ Java (รวม 8.0) นี่อาจเป็นทิศทางที่คุณต้องการสำรวจเพิ่มเติม
ฉันพิจารณาคุณสมบัติของตัวแปรทั่วโลกว่าเป็นตัวแปรที่สามารถเข้าถึงและเปลี่ยนแปลงได้ทุกที่ในรหัสโดยไม่สนใจการเรียกใช้แบบสแตติก / อินสแตนซ์หรือผ่านการอ้างอิงใด ๆ จากชั้นหนึ่งไปยังอีกชั้นหนึ่ง
โดยปกติถ้าคุณมีคลาส A
public class A {
private int myVar;
public A(int myVar) {
this.myVar = myVar;
}
public int getMyVar() {
return myVar;
}
public void setMyVar(int mewVar) {
this.myVar = newVar;
}
}
และต้องการเข้าถึงและอัปเดตmyvarในคลาส B
public class B{
private A a;
public void passA(A a){
this.a = a;
}
public void changeMyVar(int newVar){
a.setMyvar(newVar);
}
}
คุณจะต้องมีการอ้างอิงของอินสแตนซ์ของคลาส A และอัปเดตค่าในคลาส B เช่นนี้:
int initialValue = 2;
int newValue = 3;
A a = new A(initialValue);
B b = new B();
b.passA(a);
b.changeMyVar(newValue);
assertEquals(a.getMyVar(),newValue); // true
ดังนั้นวิธีการแก้ปัญหาของฉันนี้ (แม้ว่าฉันไม่แน่ใจว่ามันเป็นวิธีปฏิบัติที่ดี) คือการใช้ซิงเกิล:
public class Globals {
private static Globals globalsInstance = new Globals();
public static Globals getInstance() {
return globalsInstance;
}
private int myVar = 2;
private Globals() {
}
public int getMyVar() {
return myVar;
}
public void setMyVar(int myVar) {
this.myVar = myVar;
}
}
ตอนนี้คุณสามารถรับอินสแตนซ์ที่ไม่ซ้ำใครได้จากทุกที่ด้วย
Globals globals = Globals.getInstance();
// and read and write to myVar with the getter and setter like
int myVar = globals.getMyVar();
global.setMyVar(3);
// Get the access of global while retaining priveleges.
// You can access variables in one class from another, with provisions.
// The primitive must be protected or no modifier (seen in example).
// the first class
public class farm{
int eggs; // an integer to be set by constructor
fox afox; // declaration of a fox object
// the constructor inits
farm(){
eggs = 4;
afox = new fox(); // an instance of a fox object
// show count of eggs before the fox arrives
System.out.println("Count of eggs before: " + eggs);
// call class fox, afox method, pass myFarm as a reference
afox.stealEgg(this);
// show the farm class, myFarm, primitive value
System.out.println("Count of eggs after : " + eggs);
} // end constructor
public static void main(String[] args){
// instance of a farm class object
farm myFarm = new farm();
}; // end main
} // end class
// the second class
public class fox{
// theFarm is the myFarm object instance
// any public, protected, or "no modifier" variable is accessible
void stealEgg(farm theFarm){ --theFarm.eggs; }
} // end class
เพื่อกำหนดตัวแปรส่วนกลางคุณสามารถใช้ประโยชน์จากคำหลักคงที่
public final class Tools {
public static int a;
public static int b;
}
ตอนนี้คุณสามารถเข้าถึง a และ b ได้จากทุกที่โดยการโทร
Tools.a;
Tools.b;
Yoy นั้นถูกต้อง ... เป็นพิเศษใน J2ME ... คุณสามารถหลีกเลี่ยง NullPointerException โดยใส่ตัวสร้าง MidLet ของคุณ (การเริ่มต้น proggy) บรรทัดของโค้ดนี้:
new Tools();
สิ่งนี้ทำให้มั่นใจได้ว่าเครื่องมือจะได้รับการจัดสรรก่อนคำสั่งใด ๆ ที่ใช้
แค่นั้นแหละ!