Защо булевият обект има публичен конструктор в Java?

Документацията за конструктора new Boolean(boolean value) в Java гласи:

Забележка: Рядко е подходящо да се използва този конструктор. Освен ако не е необходим нов екземпляр, статичната фабрика valueOf(boolean) обикновено е по-добър избор. Вероятно ще доведе до значително по-добро представяне на пространството и времето.

Ако е така, защо този конструктор е публичен и не е отхвърлен? Има ли някога добра причина да използвате този конструктор вместо Boolean.valueOf()?


person mustpax    schedule 15.09.2011    source източник
comment
Integer има същия конструктор new Integer(int value) download.oracle.com/javase/1.4.2/docs/api/java/lang/   -  person lctr30    schedule 15.09.2011
comment
@Ict30 да, но има 4 милиарда възможни обекта, които могат да бъдат създадени за Integer. За Boolean има само 2. Там няма паралел.   -  person corsiKa    schedule 26.07.2012


Отговори (5)


valueOf() беше добавен само в Java 1.4, така че изглежда, че конструкторите съществуват за обратна съвместимост.

Този билет обяснява причините конструкторите да не бъдат отхвърлени:

Поради смущенията, които отхвърлянето на API може да има, в момента API трябва да бъде „активно опасен“, за да бъде отхвърлен, като Thread.stop. Въпреки че използването на този конструктор със сигурност е непрепоръчително, той не се издига (или потъва) до стандарта на опасност, за да бъде отхвърлен в JDK. В бъдеще може да добавим възможност за „очерняне“, за да маркираме API елементи, които не са толкова лоши, че да бъдат отхвърлени, но не трябва да се използват в повечето случаи. Този конструктор би бил добър кандидат за очерняне.

Не мога да се сетя за реалистичен сценарий, при който използването на Boolean конструктори би било най-добрият начин да се направи нещо полезно.

person NPE    schedule 15.09.2011
comment
Може би трябва да има анотация @discouraged или нещо, което да показва, че не е активно опасно, но всъщност няма основателна причина да го правите. - person corsiKa; 26.07.2012
comment
Ами ако някой иска да има токен за заключване, който също може да капсулира малко флаг? Може да се напише персонализиран тип за това, но Boolean вече съществува. - person supercat; 03.06.2014
comment
@supercat Бих казал, че AtomicBoolean може да е по-добър избор за това. Или Semaphore, въпреки че това може да е твърде изискано за обикновен флаг. - person JAB; 25.06.2014
comment
Това, което е необходимо, е подходящо обяснение защо това е лошо. Изглежда всички повтарят модата на папагал, че е лошо, но има много малко информация за това защо valueOf е по-добър и защо Oracle/Sun Microsystems не просто извикаха valueOf от своите конструктори и не повлияха на разработчика. - person Andrew S; 10.03.2021

Обикновено ще искате да използвате valueOf(boolean) или дори Boolean.TRUE / Boolean.FALSE константите директно.

Но помислете за сценарий, при който искате да използвате частна променлива Boolean като монитор за синхронизиране на нишки. Там ще трябва да се уверите, че използвате свой собствен екземпляр и имате пълен контрол над него.

person Costi Ciudatu    schedule 15.09.2011
comment
Това е доста маловажна причина; има буквално хиляди други обекти, които могат да се използват като монитори. Не виждам запазването на Boolean в този набор като с висок приоритет. - person dlev; 15.09.2011
comment
маловажен, но добър случай на използване, методът valueof може да върне дублиращи се обекти, понякога не искате това - person Suraj Chandran; 15.09.2011
comment
@Costi смисълът на new Boolean(boolean value) и ValueOf(boolean) е, че имате boolean и се нуждаете от Boolean, за да използвате константите, които трябва да използвате `b? Boolean.TRUE:Boolean.FALSE. С какво това е по-добро от първите два метода? - person Miserable Variable; 15.09.2011
comment
@Hemal, new създава нов екземпляр. Тъй като булевите стойности са неизменни, това обикновено е загуба на обект - valueOf() връща един от двата обекта Boolean.TRUE или Boolean.FALSE. Използването на Boolean.TRUE/FALSE е по-бързо от valueOf(), тъй като изборът на true или false се извършва по време на компилация. Разбира се, ако не знаете кое е до момента на изпълнение, няма предимство пред valueOf(). - person Ed Staub; 15.09.2011
comment
@Ed, добре, съгласен съм, че new не е толкова добра идея. И също така съм съгласен, че Boolean.TRUE е за предпочитане пред Boolean.valueOf(true), но това не е целта на дискусията. - person Miserable Variable; 15.09.2011
comment
@Hemal: Споменах Boolean.TRUE / Boolean.FALSE като опция само за сценария, когато използвате boolean литерали; така че това е същността на дискусията: използвайте Boolean.TRUE вместо Boolean.valueOf(true). Когато имате boolean b, използвайте Boolean.valueOf(b), което прилага условния оператор вместо вас. - person Costi Ciudatu; 15.09.2011
comment
@dlev: Разбира се, това не е причината този конструктор да е публичен (или причината да бъде публичен). Просто си представих сценарий, при който това може да бъде полезно. Начинът, по който го виждам, всяка примитивна обвивка предоставя конструктор, който взема примитив, а някои от тях (като Boolean и Integer) също предоставят фабричен метод valueOf, за да могат да се кешират екземпляри, когато не е необходим нов екземпляр. - person Costi Ciudatu; 15.09.2011

Друга, не непременно добра причина вероятно би била просто да го поддържате в съответствие с другите собствени обвивки.

person Timo Ohr    schedule 15.09.2011
comment
Имайте малко увереност! Това е доста прилична причина. - person dlev; 15.09.2011
comment
Най-вече се съмнявах в създателите на Java, не в себе си :) - person Timo Ohr; 15.09.2011

От Java 9, конструкторът Boolean(boolean) е отхвърлен; вижте javadoc.

За тези, които се интересуват от историята, имаше дългогодишен бъг, който призова за отхвърляне на конструктора. Той беше официално предложен в JEP 277 заедно с редица други отхвърляния.

person Stephen C    schedule 02.02.2020

Причината да не е отхвърлена е, че Java поддържа обратна съвместимост до версия 1.0

Не мога да се сетя за добра причина да използвам конструктора.

person James DW    schedule 15.09.2011
comment
Маркирането му като остарял обаче няма да го спре да бъде обратно съвместим. Всъщност това е целият смисъл. - person Timo Ohr; 15.09.2011
comment
Java обаче не поддържа обратна съвместимост с версия 1.0: няколко JDK (отгоре на главата ми, 1.4 и 1.7) въведоха конструкции, които не могат да се изпълняват на по-ранни JRE. Те просто не са склонни да нарушават каквото и да било и решиха, че този ужасен конструктор не е достатъчно опасен, за да оправдае прекъсване на обратната съвместимост. - person amalloy; 08.08.2012
comment
@amalloy Това би било съвместимост напред; обратната съвместимост е гаранцията, че конструкциите, които могат да се изпълняват на по-ранни JRE, могат да се изпълняват на по-късни (и е една от причините Java генеричните кодове да се изпълняват чрез изтриване на типове и необработените типове все още са нещо). - person JAB; 25.06.2014