prywatny końcowy statyczny -> stwórz tę zmienną tylko raz. prywatny finał -> utwórz tę zmienną dla każdego obiektu. Najpierw oszczędza pamięć, idź po nią.
user1923551
4
final staticoznacza, że ta zmienna jest stałą i wiąże się tylko z samą klasą, tj. „jedna stała zmienna na klasę”, podczas gdy finaloznacza „jedna stała zmienna na instancję”. W rezultacie nie można wstawić final staticzmiennej do konstruktora klasy, ponieważ konstruktor obejmuje nową instancję . (Możesz spróbować sam i pojawi się błąd)
LittleLittleQ,
1
Przez „nie można wstawić końcowej zmiennej statycznej do konstruktora klasy” Mam na myśli, że nie można zainicjować final staticzmiennej w konstruktorze, jedynym sposobem jest użycie inicjatora statycznego :)
LittleLittleQ
2
@ user1923551 Efekt jest odwrócony dla rzeczy, które są potrzebne tylko przez ograniczony czas w dużych aplikacjach, w aplikacjach o ograniczonej pamięci lub podczas korzystania z singletonu. Posiadanie statycznych elementów w każdej klasie zarezerwuje (ogromną) część pamięci na rzeczy, które nie są potrzebne. Może to być także wyciek pamięci, aby zadeklarować statyczne obiekty końcowe lub kolekcje.
Mam nadzieję, że będzie
Odpowiedzi:
309
Ogólnie staticoznacza „związany z samym typem , a nie z instancją typu”.
Oznacza to, że możesz odwoływać się do zmiennej statycznej bez tworzenia instancji tego typu, a każdy kod odnoszący się do zmiennej odnosi się do dokładnie tych samych danych. Porównaj to ze zmienną instancji: w takim przypadku istnieje jedna niezależna wersja zmiennej na instancję klasy. Na przykład:
Test x =newTest();Test y =newTest();
x.instanceVariable =10;
y.instanceVariable =20;System.out.println(x.instanceVariable);
drukuje 10: y.instanceVariablei x.instanceVariablesą oddzielne, bo xi yodnoszą się do różnych obiektów.
Państwo może odnosić się do elementów statycznych poprzez referencje, chociaż jest to zły pomysł, aby to zrobić. Gdybyśmy:
Test x =newTest();Test y =newTest();
x.staticVariable =10;
y.staticVariable =20;System.out.println(x.staticVariable);
to by wydrukowało 20 - jest tylko jedna zmienna, a nie jedna na instancję. Łatwiej byłoby napisać to jako:
Test x =newTest();Test y =newTest();Test.staticVariable =10;Test.staticVariable =20;System.out.println(Test.staticVariable);
To czyni zachowanie o wiele bardziej oczywistym. Nowoczesne IDE zwykle sugerują zmianę drugiego wpisu na trzeci.
Nie ma powodu, aby deklaracja inline inicjalizowała wartość w następujący sposób, ponieważ każda instancja będzie miała własną, NUMBERale zawsze o tej samej wartości (jest niezmienna i inicjowana literałem). Jest to to samo, co dla jednej final staticinstancji tylko jedna zmienna.
privatefinalint NUMBER =10;
Dlatego jeśli nie można go zmienić, nie ma sensu mieć jednej kopii na instancję.
Ale ma sens, jeśli jest inicjowany w takim konstruktorze:
// No initialization when is declaredprivatefinalint number;publicMyClass(int n){// The variable can be assigned in the constructor, but then// not modified later.
number = n;}
Teraz dla każdego wystąpienia MyClassmożemy mieć inną, ale niezmienną wartość number.
Do czasu, gdy wyliczenia były dostępne w Javie 5, statyczny finał był zwykłym sposobem deklarowania stałych.
Vineet Reynolds,
22
@Vineet: statyczne finały są wciąż sposobem deklarowania prymitywnych stałych, chyba że masz ich wyliczoną liczbę =)
Chii
@Matthew: Potencjalnie. Nie dla stałej, ale dla pewnej logicznie związanej z instancją wartości. I tak nie lubię singli.
Jon Skeet
1
Radykalne pytanie. Czy warto przy użyciu private finalponad private static finalwycisnąć / Reclaim że niewiele pamięci z klasy? Powiedzmy, że dla calculatorurządzenia z ograniczonym ram, ale z dużą ilością zasobów procesora.
Wygraj Myo Htet
1
@WinMyoHtet: Jeśli używasz pola statycznego, w sumie jest tylko jedno . Jeśli używasz pola instancji, istnieje jedno na instancję. Używanie pola statycznego będzie lepsze, chyba że nie masz żadnych instancji, w którym to przypadku i tak jest bezużyteczne.
Jon Skeet
38
Na końcowy może być przypisane różne wartości w czasie pracy, kiedy inicjowany. Na przykład
W przypadku statycznego finału wszystkie instancje mają tę samą wartość i nie można ich zmienić po pierwszej inicjalizacji.
ClassTestStatic{publicstaticfinalint a;}TestStatic t1 =newTestStatic();
t1.a =10;TestStatic t2 =newTestStatic();
t1.a =20;// ERROR, CAN'T BE ALTERED AFTER THE FIRST INITIALIZATION.
To się nie skompiluje! Do zmiennej końcowej należy albo przypisać wartość, albo mieć wartość przypisaną w jej konstruktorach. Ta odpowiedź byłaby poprawna, gdyby podano 2 konstruktory, z których każdy przypisuje „a” do innej wartości.
MattC
14
Potwierdzając, to się nie skompiluje. Jak wyrażono powyżej, zmienne instancji końcowej muszą zostać utworzone w instancji przed zakończeniem konstruktora, a zmienne klasy ostatecznej muszą zostać utworzone w instancji przed utworzeniem klasy (można użyć bloku statycznego). Dlaczego to ma tak wiele pozytywnych opinii?
Rudi Kershaw
jak zauważył MattC, nie można przypisać do zmiennej końcowej po utworzeniu tego obiektu - w rzeczywistości nie można nawet utworzyć obiektu bez podania wartości jego zmiennych końcowych ...
jamesdeath123 30.01.2015
Na wypadek, gdyby ktoś natknął się na to, proszę postępować zgodnie z odpowiedzią MattC.
Faz,
O to, jak sądzę, pytał OP, zapomniałem, że finałom można przypisać wartość w momencie tworzenia, jeśli nie została podana w momencie zgłoszenia.
Salsero69,
34
A staticpobyty zmienne w pamięci przez cały okres stosowania i jest inicjowany podczas klasowej załadunku. Za statickażdym razem, gdy newbudujesz obiekt, inicjowana jest zmienna . Ogólnie lepiej jest użyć:
privatestaticfinalint NUMBER =10;
Dlaczego? Zmniejsza to zużycie pamięci na instancję. Prawdopodobnie jest to również korzystne dla trafień w pamięci podręcznej. Ma to po prostu sens: staticpowinno się go używać do rzeczy, które są współużytkowane we wszystkich instancjach (zwanych też obiektami) określonego typu (zwanych też class).
zmienna statyczna jest również tworzona w czasie wykonywania. Dlatego możesz użyć tej zmiennej lub metody przed utworzeniem obiektu.
bobby
13
Zgodnie z konwencją kodowania Java nazwa statycznej zmiennej końcowej powinna być pisana wielkimi literami.
starblue
@Martijn Courteaux, co powiesz na sytuację, w której klasa zostanie wykorzystana raz w trakcie życia aplikacji! private final intzostanie usunięty z pamięci, gdy instancja zostanie GC'ed, podczas gdy private static final intpozostanie w pamięci przez cały okres użytkowania tej aplikacji. Co sugerujesz w powyższym scenariuszu?
MANN
@MANN: To jest bardzo teoretyczne. Nie ma dosłownie żadnego przydatnego scenariusza przypadku użycia. Może to być korzystne, jeśli masz w klasie jakieś 50000 jednostek wewnętrznych. Nawet w tym przypadku zaoszczędziłoby to 200 KB pamięci. Ponieważ mówimy o Javie, wydaje się to zupełnie nieistotne. W przypadku urządzeń krytycznych dla pamięci, porządny kompilator C lub C ++ zawsze wstawiałby te wartości całkowite, eliminując potrzebę całkowitego zwolnienia pamięci.
Martijn Courteaux
17
statyczny oznacza „związany z klasą”; bez niego zmienna jest powiązana z każdą instancją klasy. Jeśli jest statyczny, oznacza to, że będziesz mieć tylko jeden w pamięci; jeśli nie, będziesz mieć jeden dla każdego utworzonego wystąpienia. statyczny oznacza, że zmienna pozostanie w pamięci tak długo, jak klasa zostanie załadowana; bez niego zmienna może zostać wygenerowana gc, gdy jest to jej instancja.
Zmienne instancji są uzyskiwane gc za każdym razem, gdy umierają wszystkie referencje / obiekty, prawda?
Ruchir Baronia
Instancje są gc'd, ale statyka jest powiązana z klasami, a nie instancjami. Dopóki klasa pozostaje w pamięci, będziesz mógł odwoływać się do jej publicznych statycznych instancji i metod. Te przechodzą do perm gen (lub cokolwiek to jest JDK 8) i nie są generowane.
duffymo
Źle. Jeśli masz odwołanie do wystąpienia w pamięci, możesz uzyskać dostęp do dostępnych metod i wystąpień. Reszta jest błędna. Nie rozumiesz różnicy między klasą a jej instancjami.
duffymo
13
Czytając odpowiedzi, nie znalazłem żadnego prawdziwego testu, który miałby sens. Oto moje 2 centy:
Tak jak myślałem, Java robi różnicę między prymitywnymi a innymi typami. Typy pierwotne w Javie są zawsze „buforowane”, tak samo dla literałów ciągów (nie nowych obiektów String), więc nie ma różnicy między elementami statycznymi i niestatycznymi.
Istnieje jednak duplikacja pamięci dla elementów niestatycznych, jeśli nie są one instancją typu pierwotnego.
Zmiana wartości valueStatic na 10 pójdzie nawet dalej, ponieważ Java da te same adresy dwóm zmiennym int.
Autoboksowanie „int” -> Liczba całkowita powoduje tutaj zamieszanie. Widzisz, że autoboksowanie niektórych (małych) wartości int prowadzi do tego samego obiektu Integer.
dkneller 16.04.15
@StackHola @dkneller Rzeczywiście, autoboxing jest tutaj bardzo ważnym szczegółem. Podpis jest ObjectUtils.identityToString(Object). (Poza tym Java i tak nie ma żadnego odniesienia). Naprawdę przydatnym testem byłoby przydzielenie dwóch obiektów i zmiana wartości public final int FOO = 10zmiennej przy użyciu odbić Java w wymuszony sposób. Następnie sprawdź, czy drugi obiekt również zmienił swoją wartość.
Martijn Courteaux,
11
Podczas gdy inne odpowiedzi wydają się jasno wyjaśniać, że generalnie nie ma powodu, aby używać stałych niestatycznych, nie mogłem znaleźć nikogo wskazującego, że możliwe są różne instancje o różnych wartościach dla ich zmiennych stałych.
Rozważ następujący przykład:
publicclassTestClass{privatefinalstaticdouble NUMBER =Math.random();publicTestClass(){System.out.println(NUMBER);}}
Utworzenie trzech instancji TestClass spowoduje wydrukowanie tej samej losowej wartości trzy razy, ponieważ tylko jedna wartość jest generowana i zapisywana w stałej statycznej.
Jednak zamiast tego spróbuj wykonać następujący przykład:
publicclassTestClass{privatefinaldouble NUMBER =Math.random();publicTestClass(){System.out.println(NUMBER);}}
Utworzenie trzech instancji TestClass spowoduje teraz wydrukowanie trzech różnych losowych wartości, ponieważ każda instancja ma swoją własną, losowo generowaną stałą wartość.
Nie mogę wymyślić żadnej sytuacji, w której przydałoby się mieć różne stałe wartości w różnych przypadkach, ale mam nadzieję, że to pomaga wskazać, że istnieje wyraźna różnica między finałami statycznymi i niestatycznymi.
publicclassStaticVariable{staticint noOfInstances;StaticVariable(){
noOfInstances++;}publicstaticvoid main(String[] args){StaticVariable sv1 =newStaticVariable();System.out.println("No. of instances for sv1 : "+ sv1.noOfInstances);StaticVariable sv2 =newStaticVariable();System.out.println("No. of instances for sv1 : "+ sv1.noOfInstances);System.out.println("No. of instances for st2 : "+ sv2.noOfInstances);StaticVariable sv3 =newStaticVariable();System.out.println("No. of instances for sv1 : "+ sv1.noOfInstances);System.out.println("No. of instances for sv2 : "+ sv2.noOfInstances);System.out.println("No. of instances for sv3 : "+ sv3.noOfInstances);}}
Dane wyjściowe programu podano poniżej:
Jak widać w tym przykładzie, każdy obiekt ma własną kopię zmiennej klasy.
C:\java>java StaticVariableNo. of instances for sv1 :1No. of instances for sv1 :2No. of instances for st2 :2No. of instances for sv1 :3No. of instances for sv2 :3No. of instances for sv3 :3
Z przeprowadzonych przeze mnie testów statyczne zmienne końcowe nie są takie same jak zmienne końcowe (niestatyczne)! Ostateczne (niestatyczne) zmienne mogą różnić się w zależności od obiektu !!! Ale to tylko wtedy, gdy inicjalizacja zostanie wykonana w konstruktorze! (Jeśli nie zostanie zainicjowany z konstruktora, to tylko marnotrawstwo pamięci, ponieważ tworzy końcowe zmienne dla każdego tworzonego obiektu, którego nie można zmienić).
Na przykład:
class A
{finalint f;staticfinalint sf =5;
A(int num){this.f = num;}void show(){System.out.printf("About Object: %s\n Final: %d\n Static Final: %d\n\n",this.toString(),this.f, sf);}publicstaticvoid main(String[] args){
A ob1 =new A(14);
ob1.show();
A ob2 =new A(21);
ob2.show();}}
Na ekranie pojawia się:
O obiekcie: A @ addbf1 Finał: 14 Statyczny finał: 5
O obiekcie: A @ 530daa Finał: 21 Statyczny finał: 5
Anonimowy student informatyki pierwszego roku, Grecja
Co więcej, odpowiedź Jona, jeśli użyjesz statycznego finału, będzie zachowywał się jak swego rodzaju „definicja”. Po skompilowaniu klasy, która z niej korzysta, będzie ona spalona w skompilowanym pliku .class. Sprawdź mój wątek na ten temat tutaj .
Dla twojego głównego celu: Jeśli nie użyjesz NUMERU inaczej w różnych instancjach klasy, radzę użyć ostatecznego i statycznego.
(Trzeba tylko pamiętać, aby nie kopiować skompilowanych plików klas, nie biorąc pod uwagę możliwych problemów, takich jak ten opisany w moim studium przypadku. Większość przypadków nie występuje, nie martw się :))
Aby pokazać, jak używać różnych wartości w instancjach, sprawdź ten kod:
Czy mógłby Pan wyjaśnić, co jest lepsze i dlaczego?
Daniel
2
Kolejny prosty przykład, aby zrozumieć użycie statycznych, statycznych zmiennych końcowych, końcowych. Komentarze do kodu mają odpowiednie wyjaśnienie.
publicclassCity{// base price that is always same for all objects[For all cities].privatestaticdouble iphone_base_price =10000;// this is total price = iphone_base_price+iphone_diff;privatedouble iphone_citi_price;// extra price added to iphone_base_price. It is constant per city. Every// city has its own difference defined,privatefinaldouble iphone_diff;privateString cityName ="";// static final will be accessible everywhere within the class but cant be// changed once initialized.privatestaticfinalString countryName ="India";publicCity(String cityName,double iphone_diff){super();this.iphone_diff = iphone_diff;
iphone_citi_price = iphone_base_price + iphone_diff;this.cityName = cityName;}/**
* get phone price
*
* @return
*/privatedouble getPrice(){return iphone_citi_price;}/**
* Get city name
*
* @return
*/privateString getCityName(){return cityName;}publicstaticvoid main(String[] args){// 300 is theCity newyork =newCity("Newyork",300);System.out.println(newyork.getPrice()+" "+ newyork.getCityName());City california =newCity("California",800);System.out.println(california.getPrice()+" "+ california.getCityName());// We cant write below statement as a final variable can not be// reassigned// california.iphone_diff=1000; //************************// base price is defined for a class and not per instances.// For any number of object creation, static variable's value would be the same// for all instances until and unless changed.// Also it is accessible anywhere inside a class.
iphone_base_price =9000;City delhi =newCity("delhi",400);System.out.println(delhi.getPrice()+" "+ delhi.getCityName());City moscow =newCity("delhi",500);System.out.println(moscow.getPrice()+" "+ moscow.getCityName());// Here countryName is accessible as it is static but we can not change it as it is final as well. //Something are meant to be accessible with no permission to modify it. //Try un-commenting below statementsSystem.out.println(countryName);// countryName="INDIA";// System.out.println(countryName);}}
Nie ma dużej różnicy, ponieważ oba są stałymi. W przypadku większości obiektów danych klasy statyczny oznaczałby coś związanego z samą klasą, ponieważ istnieje tylko jedna kopia, bez względu na to, ile obiektów utworzono za pomocą nowego.
Ponieważ jest to stała, może nie być przechowywana ani w klasie, ani w instancji, ale kompilator nadal nie pozwoli ci uzyskać dostępu do obiektów instancji z metody statycznej, nawet jeśli wie, czym one byłyby. Istnienie interfejsu API odbicia może również wymagać bezsensownej pracy, jeśli nie zostanie on statyczny.
Ponieważ zmienna w klasie jest deklarowana jako końcowa ORAZ zainicjowana w tym samym poleceniu, nie ma absolutnie żadnego powodu, aby nie deklarować jej jako statycznej, ponieważ będzie miała tę samą wartość bez względu na instancję. Tak więc wszystkie instancje mogą dzielić ten sam adres pamięci dla wartości, oszczędzając w ten sposób czas przetwarzania, eliminując potrzebę tworzenia nowej zmiennej dla każdej instancji i oszczędzając pamięć, dzieląc 1 wspólny adres.
prywatny statyczny finał będzie uważany za stały, a do stałej można uzyskać dostęp tylko w tej klasie. Ponieważ uwzględniono słowo kluczowe static, wartość będzie stała dla wszystkich obiektów klasy.
wartość końcowa prywatnej zmiennej będzie podobna do stałej na obiekt.
Możesz odnieść się do java.lang.String lub poszukać przykładu poniżej.
Statyczny jest tym samym elementem we wszystkich instancjach klasy i samej klasie.
Non-static jest jednym dla każdej instancji (obiektu), a więc w swoim dokładnym przypadku to strata pamięci, jeśli nie umieścić statycznej.
Jeśli zaznaczysz tę zmienną jako statyczną, to jak wiesz, będziesz potrzebować metod statycznych, aby ponownie uzyskać dostęp do tych wartości, będzie to przydatne, jeśli już myślisz o użyciu tych zmiennych tylko w metodach statycznych. Jeśli tak jest, to byłby najlepszy.
Możesz jednak teraz ustawić zmienną jako publiczną, ponieważ nikt nie może jej modyfikować tak jak „System.out”, to znowu zależy od twoich intencji i tego, co chcesz osiągnąć.
Metody statyczne nie byłyby wymagane do uzyskania dostępu do zmiennych statycznych - myślę, że myślisz o „dostępie do zmiennych instancji z metod statycznych” (niedozwolone).
ataulm
0
Powiedzmy, że jeśli klasa nie będzie miała więcej niż jednej instancji, to która z nich zajmie więcej pamięci:
prywatny statyczny końcowy int ID = 250; lub prywatny końcowy int ID = 250;
Zrozumiałem, że statyczny będzie odnosił się do typu klasy z tylko jedną kopią w pamięci i niestatyczny będzie w nowej lokalizacji pamięci dla każdej zmiennej instancji. Jednak wewnętrznie, jeśli porównamy tylko 1 instancję tej samej klasy (tzn. Nie utworzy się więcej niż 1 instancja), to czy jest jakiś narzut związany z przestrzenią używaną przez 1 statyczną zmienną końcową?
Proszę nie powtarzać, jakie inne odpowiedzi już zawierały.
użytkownik nieznany
0
Zmienna statyczna należy do klasy (co oznacza, że wszystkie obiekty współużytkują tę zmienną). Zmienna niestatyczna należy do każdego obiektu.
publicclassExperimentFinal{privatefinalint a;privatestaticfinalint b =999;publicExperimentFinal(int a){super();this.a = a;}publicint getA(){return a;}publicint getB(){return b;}publicvoid print(int a,int b){System.out.println("final int: "+ a +" \nstatic final int: "+ b);}publicstaticvoid main(String[] args){ExperimentFinal test =newExperimentFinal(9);
test.print(test.getA(), test.getB());}}
Jak widać powyżej, dla „final int” możemy przypisać naszą zmienną do każdej instancji (obiektu) klasy, jednak dla „static int int” powinniśmy przypisać zmienną w klasie (zmienna statyczna należy do klasy ).
Jeśli użyjesz parametru static, wartość zmiennej będzie taka sama we wszystkich twoich instancjach, jeśli zmienisz się w jednej instancji, inne też się zmienią.
Ostateczne: po przypisaniu zmiennej końcowej zawsze zawiera tę samą wartość. wszędzie tam, gdzie zmienna jest statyczna lub niestatyczna: będzie tylko jedną zmienną dla wszystkich instancji zainicjowanych jeden raz w pamięci
publicclassLengthDemo{publicstaticvoid main(String[] args){Rectangle box =newRectangle();System.out.println("Sending the value 10.0 "+"to the setLength method.");
box.setLength(10.0);System.out.println("Done.");}}
Słowo kluczowe „statyczny” sprawia, że właściwość zmiennej jest klasą, a nie poszczególnymi instancjami klasy. Będzie jedna kopia tej zmiennej, która będzie współużytkowana przez wszystkie instancje tej klasy. Każda zmiana stanu zmiennej statycznej zostanie odzwierciedlona we wszystkich instancjach. Dodaj końcowy do statycznego, a otrzymamy zmienną, która została zainicjowana raz na zawsze w czasie ładowania klasy i nie może być później zmieniona przez żadną instancję klasy. Ostateczne zmienne statyczne należy zainicjować w czasie deklaracji, w przeciwnym razie wystąpi błąd czasu kompilacji. Jeśli chodzi o pole wystąpienia prywatnego, odnosi się ono do właściwości / stanu obiektu / wystąpienia klasy. Każde wystąpienie / obiekt klasy będzie miało własną kopię zmiennej wystąpienia. Gdy zmienna instancji zostanie zadeklarowana jako ostateczna, oznacza to, że nie możemy zmienić jego wartości dla tego wystąpienia. W tym celu musimy zainicjować zmienną końcową w deklaracji lub w konstruktorze. Jeśli nie zostanie wykonana w żadnej z nich, pojawi się błąd czasu kompilacji. Po zainicjowaniu, jeśli spróbujesz ponownie przypisać wartość, pojawi się błąd czasu kompilacji. Użyj statycznych zmiennych końcowych, w których dane będą udostępniane we wszystkich instancjach klasy, a chcesz, aby dane były tylko do odczytu. Użyj zmiennej końcowej instancji, jeśli chcesz reprezentować niektóre dane, które należą do każdej pojedynczej instancji klasy, ale tylko raz przechowywanych nie można zmienić. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu. W tym celu musimy zainicjować zmienną końcową w deklaracji lub w konstruktorze. Jeśli nie zostanie wykonana w żadnej z nich, pojawi się błąd czasu kompilacji. Po zainicjowaniu, jeśli spróbujesz ponownie przypisać wartość, pojawi się błąd czasu kompilacji. Użyj statycznych zmiennych końcowych, w których dane będą udostępniane we wszystkich instancjach klasy, a chcesz, aby dane były tylko do odczytu. Użyj zmiennej końcowej instancji, jeśli chcesz reprezentować niektóre dane, które należą do każdej pojedynczej instancji klasy, ale tylko raz przechowywanych nie można zmienić. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu. W tym celu musimy zainicjować zmienną końcową w deklaracji lub w konstruktorze. Jeśli nie zostanie wykonana w żadnej z nich, pojawi się błąd czasu kompilacji. Po zainicjowaniu, jeśli spróbujesz ponownie przypisać wartość, pojawi się błąd czasu kompilacji. Użyj statycznych zmiennych końcowych, w których dane będą udostępniane we wszystkich instancjach klasy, a chcesz, aby dane były tylko do odczytu. Użyj zmiennej końcowej instancji, jeśli chcesz reprezentować niektóre dane, które należą do każdej pojedynczej instancji klasy, ale tylko raz przechowywanych nie można zmienić. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu. Jeśli nie zostanie wykonane w żadnym z nich, pojawi się błąd czasu kompilacji. Po zainicjowaniu, jeśli spróbujesz ponownie przypisać wartość, pojawi się błąd czasu kompilacji. Użyj statycznych zmiennych końcowych, w których dane będą udostępniane we wszystkich instancjach klasy, a chcesz, aby dane były tylko do odczytu. Użyj zmiennej końcowej instancji, jeśli chcesz reprezentować niektóre dane, które należą do każdej pojedynczej instancji klasy, ale tylko raz przechowywanych nie można zmienić. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu. Jeśli nie zostanie wykonane w żadnym z nich, pojawi się błąd czasu kompilacji. Po zainicjowaniu, jeśli spróbujesz ponownie przypisać wartość, pojawi się błąd czasu kompilacji. Użyj statycznych zmiennych końcowych, w których dane będą udostępniane we wszystkich instancjach klasy, a chcesz, aby dane były tylko do odczytu. Użyj zmiennej końcowej instancji, jeśli chcesz reprezentować niektóre dane, które należą do każdej pojedynczej instancji klasy, ale tylko raz przechowywanych nie można zmienić. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu. Użyj statycznych zmiennych końcowych, w których dane będą udostępniane we wszystkich instancjach klasy, a chcesz, aby dane były tylko do odczytu. Użyj zmiennej końcowej instancji, jeśli chcesz reprezentować niektóre dane, które należą do każdej pojedynczej instancji klasy, ale tylko raz przechowywanych nie można zmienić. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu. Użyj statycznych zmiennych końcowych, w których dane będą udostępniane we wszystkich instancjach klasy, a chcesz, aby dane były tylko do odczytu. Użyj zmiennej końcowej instancji, jeśli chcesz reprezentować niektóre dane, które należą do każdej pojedynczej instancji klasy, ale tylko raz przechowywanych nie można zmienić. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu.
final static
oznacza, że ta zmienna jest stałą i wiąże się tylko z samą klasą, tj. „jedna stała zmienna na klasę”, podczas gdyfinal
oznacza „jedna stała zmienna na instancję”. W rezultacie nie można wstawićfinal static
zmiennej do konstruktora klasy, ponieważ konstruktor obejmuje nową instancję . (Możesz spróbować sam i pojawi się błąd)final static
zmiennej w konstruktorze, jedynym sposobem jest użycie inicjatora statycznego :)Odpowiedzi:
Ogólnie
static
oznacza „związany z samym typem , a nie z instancją typu”.Oznacza to, że możesz odwoływać się do zmiennej statycznej bez tworzenia instancji tego typu, a każdy kod odnoszący się do zmiennej odnosi się do dokładnie tych samych danych. Porównaj to ze zmienną instancji: w takim przypadku istnieje jedna niezależna wersja zmiennej na instancję klasy. Na przykład:
drukuje 10:
y.instanceVariable
ix.instanceVariable
są oddzielne, box
iy
odnoszą się do różnych obiektów.Państwo może odnosić się do elementów statycznych poprzez referencje, chociaż jest to zły pomysł, aby to zrobić. Gdybyśmy:
to by wydrukowało 20 - jest tylko jedna zmienna, a nie jedna na instancję. Łatwiej byłoby napisać to jako:
To czyni zachowanie o wiele bardziej oczywistym. Nowoczesne IDE zwykle sugerują zmianę drugiego wpisu na trzeci.
Nie ma powodu, aby deklaracja inline inicjalizowała wartość w następujący sposób, ponieważ każda instancja będzie miała własną,
NUMBER
ale zawsze o tej samej wartości (jest niezmienna i inicjowana literałem). Jest to to samo, co dla jednejfinal static
instancji tylko jedna zmienna.Dlatego jeśli nie można go zmienić, nie ma sensu mieć jednej kopii na instancję.
Ale ma sens, jeśli jest inicjowany w takim konstruktorze:
Teraz dla każdego wystąpienia
MyClass
możemy mieć inną, ale niezmienną wartośćnumber
.źródło
private final
ponadprivate static final
wycisnąć / Reclaim że niewiele pamięci z klasy? Powiedzmy, że dlacalculator
urządzenia z ograniczonym ram, ale z dużą ilością zasobów procesora.Na końcowy może być przypisane różne wartości w czasie pracy, kiedy inicjowany. Na przykład
Zatem każde wystąpienie ma inną wartość pola a .
W przypadku statycznego finału wszystkie instancje mają tę samą wartość i nie można ich zmienić po pierwszej inicjalizacji.
źródło
A
static
pobyty zmienne w pamięci przez cały okres stosowania i jest inicjowany podczas klasowej załadunku. Zastatic
każdym razem, gdynew
budujesz obiekt, inicjowana jest zmienna . Ogólnie lepiej jest użyć:Dlaczego? Zmniejsza to zużycie pamięci na instancję. Prawdopodobnie jest to również korzystne dla trafień w pamięci podręcznej. Ma to po prostu sens:
static
powinno się go używać do rzeczy, które są współużytkowane we wszystkich instancjach (zwanych też obiektami) określonego typu (zwanych teżclass
).źródło
private final int
zostanie usunięty z pamięci, gdy instancja zostanie GC'ed, podczas gdyprivate static final int
pozostanie w pamięci przez cały okres użytkowania tej aplikacji. Co sugerujesz w powyższym scenariuszu?statyczny oznacza „związany z klasą”; bez niego zmienna jest powiązana z każdą instancją klasy. Jeśli jest statyczny, oznacza to, że będziesz mieć tylko jeden w pamięci; jeśli nie, będziesz mieć jeden dla każdego utworzonego wystąpienia. statyczny oznacza, że zmienna pozostanie w pamięci tak długo, jak klasa zostanie załadowana; bez niego zmienna może zostać wygenerowana gc, gdy jest to jej instancja.
źródło
Czytając odpowiedzi, nie znalazłem żadnego prawdziwego testu, który miałby sens. Oto moje 2 centy:
Wyniki dla pierwszego obiektu:
Wyniki dla drugiego obiektu:
Wniosek:
Tak jak myślałem, Java robi różnicę między prymitywnymi a innymi typami. Typy pierwotne w Javie są zawsze „buforowane”, tak samo dla literałów ciągów (nie nowych obiektów String), więc nie ma różnicy między elementami statycznymi i niestatycznymi.
Istnieje jednak duplikacja pamięci dla elementów niestatycznych, jeśli nie są one instancją typu pierwotnego.
Zmiana wartości valueStatic na 10 pójdzie nawet dalej, ponieważ Java da te same adresy dwóm zmiennym int.
źródło
ObjectUtils.identityToString(Object)
. (Poza tym Java i tak nie ma żadnego odniesienia). Naprawdę przydatnym testem byłoby przydzielenie dwóch obiektów i zmiana wartościpublic final int FOO = 10
zmiennej przy użyciu odbić Java w wymuszony sposób. Następnie sprawdź, czy drugi obiekt również zmienił swoją wartość.Podczas gdy inne odpowiedzi wydają się jasno wyjaśniać, że generalnie nie ma powodu, aby używać stałych niestatycznych, nie mogłem znaleźć nikogo wskazującego, że możliwe są różne instancje o różnych wartościach dla ich zmiennych stałych.
Rozważ następujący przykład:
Utworzenie trzech instancji TestClass spowoduje wydrukowanie tej samej losowej wartości trzy razy, ponieważ tylko jedna wartość jest generowana i zapisywana w stałej statycznej.
Jednak zamiast tego spróbuj wykonać następujący przykład:
Utworzenie trzech instancji TestClass spowoduje teraz wydrukowanie trzech różnych losowych wartości, ponieważ każda instancja ma swoją własną, losowo generowaną stałą wartość.
Nie mogę wymyślić żadnej sytuacji, w której przydałoby się mieć różne stałe wartości w różnych przypadkach, ale mam nadzieję, że to pomaga wskazać, że istnieje wyraźna różnica między finałami statycznymi i niestatycznymi.
źródło
Jak już powiedział Jon, zmienna statyczna, zwana także zmienną klasową, jest zmienną, która istnieje między instancjami klasy.
Tutaj znalazłem przykład :
Dane wyjściowe programu podano poniżej:
Jak widać w tym przykładzie, każdy obiekt ma własną kopię zmiennej klasy.
źródło
Z przeprowadzonych przeze mnie testów statyczne zmienne końcowe nie są takie same jak zmienne końcowe (niestatyczne)! Ostateczne (niestatyczne) zmienne mogą różnić się w zależności od obiektu !!! Ale to tylko wtedy, gdy inicjalizacja zostanie wykonana w konstruktorze! (Jeśli nie zostanie zainicjowany z konstruktora, to tylko marnotrawstwo pamięci, ponieważ tworzy końcowe zmienne dla każdego tworzonego obiektu, którego nie można zmienić).
Na przykład:
Na ekranie pojawia się:
O obiekcie: A @ addbf1 Finał: 14 Statyczny finał: 5
O obiekcie: A @ 530daa Finał: 21 Statyczny finał: 5
Anonimowy student informatyki pierwszego roku, Grecja
źródło
Co więcej, odpowiedź Jona, jeśli użyjesz statycznego finału, będzie zachowywał się jak swego rodzaju „definicja”. Po skompilowaniu klasy, która z niej korzysta, będzie ona spalona w skompilowanym pliku .class. Sprawdź mój wątek na ten temat tutaj .
Dla twojego głównego celu: Jeśli nie użyjesz NUMERU inaczej w różnych instancjach klasy, radzę użyć ostatecznego i statycznego. (Trzeba tylko pamiętać, aby nie kopiować skompilowanych plików klas, nie biorąc pod uwagę możliwych problemów, takich jak ten opisany w moim studium przypadku. Większość przypadków nie występuje, nie martw się :))
Aby pokazać, jak używać różnych wartości w instancjach, sprawdź ten kod:
źródło
Oto moje dwa centy:
Przykład:
Kluczem jest to, że zmienne i funkcje mogą zwracać różne wartości, dlatego do zmiennych końcowych można przypisywać różne wartości.
źródło
Kolejny prosty przykład, aby zrozumieć użycie statycznych, statycznych zmiennych końcowych, końcowych. Komentarze do kodu mają odpowiednie wyjaśnienie.
źródło
bardzo mało i statycznie
Nie ma dużej różnicy, ponieważ oba są stałymi. W przypadku większości obiektów danych klasy statyczny oznaczałby coś związanego z samą klasą, ponieważ istnieje tylko jedna kopia, bez względu na to, ile obiektów utworzono za pomocą nowego.
Ponieważ jest to stała, może nie być przechowywana ani w klasie, ani w instancji, ale kompilator nadal nie pozwoli ci uzyskać dostępu do obiektów instancji z metody statycznej, nawet jeśli wie, czym one byłyby. Istnienie interfejsu API odbicia może również wymagać bezsensownej pracy, jeśli nie zostanie on statyczny.
źródło
Ponieważ zmienna w klasie jest deklarowana jako końcowa ORAZ zainicjowana w tym samym poleceniu, nie ma absolutnie żadnego powodu, aby nie deklarować jej jako statycznej, ponieważ będzie miała tę samą wartość bez względu na instancję. Tak więc wszystkie instancje mogą dzielić ten sam adres pamięci dla wartości, oszczędzając w ten sposób czas przetwarzania, eliminując potrzebę tworzenia nowej zmiennej dla każdej instancji i oszczędzając pamięć, dzieląc 1 wspólny adres.
źródło
prywatny statyczny finał będzie uważany za stały, a do stałej można uzyskać dostęp tylko w tej klasie. Ponieważ uwzględniono słowo kluczowe static, wartość będzie stała dla wszystkich obiektów klasy.
wartość końcowa prywatnej zmiennej będzie podobna do stałej na obiekt.
Możesz odnieść się do java.lang.String lub poszukać przykładu poniżej.
//Wynik:
źródło
Statyczny jest tym samym elementem we wszystkich instancjach klasy i samej klasie.
Non-static jest jednym dla każdej instancji (obiektu), a więc w swoim dokładnym przypadku to strata pamięci, jeśli nie umieścić statycznej.
źródło
Jeśli zaznaczysz tę zmienną jako statyczną, to jak wiesz, będziesz potrzebować metod statycznych, aby ponownie uzyskać dostęp do tych wartości, będzie to przydatne, jeśli już myślisz o użyciu tych zmiennych tylko w metodach statycznych. Jeśli tak jest, to byłby najlepszy.
Możesz jednak teraz ustawić zmienną jako publiczną, ponieważ nikt nie może jej modyfikować tak jak „System.out”, to znowu zależy od twoich intencji i tego, co chcesz osiągnąć.
źródło
Powiedzmy, że jeśli klasa nie będzie miała więcej niż jednej instancji, to która z nich zajmie więcej pamięci:
prywatny statyczny końcowy int ID = 250; lub prywatny końcowy int ID = 250;
Zrozumiałem, że statyczny będzie odnosił się do typu klasy z tylko jedną kopią w pamięci i niestatyczny będzie w nowej lokalizacji pamięci dla każdej zmiennej instancji. Jednak wewnętrznie, jeśli porównamy tylko 1 instancję tej samej klasy (tzn. Nie utworzy się więcej niż 1 instancja), to czy jest jakiś narzut związany z przestrzenią używaną przez 1 statyczną zmienną końcową?
źródło
Zmienna statyczna należy do klasy (co oznacza, że wszystkie obiekty współużytkują tę zmienną). Zmienna niestatyczna należy do każdego obiektu.
Jak widać powyżej, dla „final int” możemy przypisać naszą zmienną do każdej instancji (obiektu) klasy, jednak dla „static int int” powinniśmy przypisać zmienną w klasie (zmienna statyczna należy do klasy ).
źródło
Jeśli użyjesz parametru static, wartość zmiennej będzie taka sama we wszystkich twoich instancjach, jeśli zmienisz się w jednej instancji, inne też się zmienią.
źródło
Ostateczne: po przypisaniu zmiennej końcowej zawsze zawiera tę samą wartość. wszędzie tam, gdzie zmienna jest statyczna lub niestatyczna: będzie tylko jedną zmienną dla wszystkich instancji zainicjowanych jeden raz w pamięci
źródło
To może pomóc
źródło
Słowo kluczowe „statyczny” sprawia, że właściwość zmiennej jest klasą, a nie poszczególnymi instancjami klasy. Będzie jedna kopia tej zmiennej, która będzie współużytkowana przez wszystkie instancje tej klasy. Każda zmiana stanu zmiennej statycznej zostanie odzwierciedlona we wszystkich instancjach. Dodaj końcowy do statycznego, a otrzymamy zmienną, która została zainicjowana raz na zawsze w czasie ładowania klasy i nie może być później zmieniona przez żadną instancję klasy. Ostateczne zmienne statyczne należy zainicjować w czasie deklaracji, w przeciwnym razie wystąpi błąd czasu kompilacji. Jeśli chodzi o pole wystąpienia prywatnego, odnosi się ono do właściwości / stanu obiektu / wystąpienia klasy. Każde wystąpienie / obiekt klasy będzie miało własną kopię zmiennej wystąpienia. Gdy zmienna instancji zostanie zadeklarowana jako ostateczna, oznacza to, że nie możemy zmienić jego wartości dla tego wystąpienia. W tym celu musimy zainicjować zmienną końcową w deklaracji lub w konstruktorze. Jeśli nie zostanie wykonana w żadnej z nich, pojawi się błąd czasu kompilacji. Po zainicjowaniu, jeśli spróbujesz ponownie przypisać wartość, pojawi się błąd czasu kompilacji. Użyj statycznych zmiennych końcowych, w których dane będą udostępniane we wszystkich instancjach klasy, a chcesz, aby dane były tylko do odczytu. Użyj zmiennej końcowej instancji, jeśli chcesz reprezentować niektóre dane, które należą do każdej pojedynczej instancji klasy, ale tylko raz przechowywanych nie można zmienić. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu. W tym celu musimy zainicjować zmienną końcową w deklaracji lub w konstruktorze. Jeśli nie zostanie wykonana w żadnej z nich, pojawi się błąd czasu kompilacji. Po zainicjowaniu, jeśli spróbujesz ponownie przypisać wartość, pojawi się błąd czasu kompilacji. Użyj statycznych zmiennych końcowych, w których dane będą udostępniane we wszystkich instancjach klasy, a chcesz, aby dane były tylko do odczytu. Użyj zmiennej końcowej instancji, jeśli chcesz reprezentować niektóre dane, które należą do każdej pojedynczej instancji klasy, ale tylko raz przechowywanych nie można zmienić. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu. W tym celu musimy zainicjować zmienną końcową w deklaracji lub w konstruktorze. Jeśli nie zostanie wykonana w żadnej z nich, pojawi się błąd czasu kompilacji. Po zainicjowaniu, jeśli spróbujesz ponownie przypisać wartość, pojawi się błąd czasu kompilacji. Użyj statycznych zmiennych końcowych, w których dane będą udostępniane we wszystkich instancjach klasy, a chcesz, aby dane były tylko do odczytu. Użyj zmiennej końcowej instancji, jeśli chcesz reprezentować niektóre dane, które należą do każdej pojedynczej instancji klasy, ale tylko raz przechowywanych nie można zmienić. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu. Jeśli nie zostanie wykonane w żadnym z nich, pojawi się błąd czasu kompilacji. Po zainicjowaniu, jeśli spróbujesz ponownie przypisać wartość, pojawi się błąd czasu kompilacji. Użyj statycznych zmiennych końcowych, w których dane będą udostępniane we wszystkich instancjach klasy, a chcesz, aby dane były tylko do odczytu. Użyj zmiennej końcowej instancji, jeśli chcesz reprezentować niektóre dane, które należą do każdej pojedynczej instancji klasy, ale tylko raz przechowywanych nie można zmienić. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu. Jeśli nie zostanie wykonane w żadnym z nich, pojawi się błąd czasu kompilacji. Po zainicjowaniu, jeśli spróbujesz ponownie przypisać wartość, pojawi się błąd czasu kompilacji. Użyj statycznych zmiennych końcowych, w których dane będą udostępniane we wszystkich instancjach klasy, a chcesz, aby dane były tylko do odczytu. Użyj zmiennej końcowej instancji, jeśli chcesz reprezentować niektóre dane, które należą do każdej pojedynczej instancji klasy, ale tylko raz przechowywanych nie można zmienić. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu. Użyj statycznych zmiennych końcowych, w których dane będą udostępniane we wszystkich instancjach klasy, a chcesz, aby dane były tylko do odczytu. Użyj zmiennej końcowej instancji, jeśli chcesz reprezentować niektóre dane, które należą do każdej pojedynczej instancji klasy, ale tylko raz przechowywanych nie można zmienić. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu. Użyj statycznych zmiennych końcowych, w których dane będą udostępniane we wszystkich instancjach klasy, a chcesz, aby dane były tylko do odczytu. Użyj zmiennej końcowej instancji, jeśli chcesz reprezentować niektóre dane, które należą do każdej pojedynczej instancji klasy, ale tylko raz przechowywanych nie można zmienić. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu. Użycie słowa kluczowego statycznego i instancji zależy od potrzeb projektowych i tego, co dane reprezentują w domenie. Jeśli dane są używane we wszystkich instancjach klasy, nie ma potrzeby oddzielnych odwołań do kopii / pamięci dla każdego obiektu.
źródło