Кіріспе

Java бағдарламалау тілі мен Java бағдарламалық платформасының сын-пікірлері Java бағдарламалау тілі мен Java бағдарламалық платформасы дизайн таңдаулары үшін сынға ұшырады, соның ішінде жалпыламаларды іске асыру, мәжбүрлі объектке бағдарланған бағдарламалау, қолтаңбасыз сандарды өңдеу, жылжымалы нүктелік арифметиканы іске асыру және негізгі Java VM іске асырылуындағы қауіпсіздік осалдықтарының тарихы. Java-да жазылған бағдарламалық қамтамасыз ету, әсіресе оның алғашқы нұсқалары, басқа бағдарламалау тілдерінде жазылған бағдарламалық қамтамасыз етумен салыстырғанда оның өнімділігі үшін сынға ұшырады. Жасаушылар сонымен қатар, Java-ның әртүрлі орындалуларындағы айырмашылықтарды, олардың барлығымен жұмыс істеуі керек күрделі Java бағдарламаларын жазу кезінде ескеру керектігін атап өтті.

Тексерілген ерекшеліктер

Java-да тексерілген ерекшеліктер енгізілген, онда әдіс әдіс қолтаңбасына тастайтын тексерілген ерекшеліктерді жариялауы керек. Бұл қажетсіз көп сөзді стандартты кодқа әкелуі мүмкін. Тексерілген ерекшеліктерді іске асыруда Java-ға ешбір негізгі тіл ерген жоқ.

Есімдікке бағдарлану

Жава бағдарламалаушыларды бір-бірімен өзара әрекеттесетін зат есімдер (сыныптар) тұрғысынан шешімді ойлауға және етістіктерді (әдістерді) сол зат есімде немесе сол зат есімде орындалатын операциялар ретінде ойлауға шақырады. Стив Йегге бұл тілдің экспрессивтілігіне қажетсіз шектеулер әкеледі деп айтады, өйткені сыныпта оған әсер ететін бірнеше функциялар болуы мүмкін, бірақ функция сыныпқа байланысты және бірнеше типтерде ешқашан әрекет ете алмайды. Көптеген басқа көп парадигмалы тілдер жоғары деңгейдегі конструкция ретінде функцияларды қолдайды. Функция жүктемесі (бір етістік, бірнеше есімдер) және жалпы функциялар (бір етістік, белгілі бір қасиеттері бар есімдер отбасы) сияқты басқа да мүмкіндіктермен біріктірілгенде, бағдарламашы белгілі бір мәселені есімдер немесе етістіктер тұрғысынан шешуді шеше алады. Java 8 нұсқасы кейбір функционалдық бағдарламалау мүмкіндіктерін енгізді.

Белгісіз бүтін сандар түрлері

Java-да таңбасыз бүтін сан түрлерінің аналық түрі жоқ. Қолтаңбасыз деректер көбінесе C тілінде жазылған бағдарламалардан жасалады, ал бұл түрлердің болмауы C және Java арасында тікелей деректер алмасуды болдырмайды. Белгісіз үлкен сандар сандық өңдеудің бірқатар салаларында, соның ішінде криптографияда қолданылады, бұл Java-ны осы тапсырмалар үшін пайдалануды ыңғайсыз ете алады. Бұл мәселені конверсия коды мен үлкен деректер түрлерін пайдалану арқылы шешуге болатын болса да, бұл қолтаңбасыз деректерді өңдеу үшін Java-ны қолдануды қиындатады. 32 биттік қолтаңбаланған бүтін сан 16 биттік қолтаңбасыз құнды жоғалтусыз, ал 64 биттік қолтаңбаланған бүтін сан 32 биттік қолтаңбасыз бүтін санды ұстау үшін пайдаланылуы мүмкін, 64 биттік қолтаңбасыз бүтін санды ұстау үшін үлкен түрі жоқ. Барлық жағдайларда, тұтынылатын жад екі есеге көбейе алады және әдетте екілік толықтыруға негізделген кез келген логика қайта жазылуы керек. Егер функцияларды шақыруды абстракцияласа, онда басқа тілдерге тән көптеген операциялар үшін қажет болады. Яғни, Java-ның қол қойылған бүтін сандарын бірдей өлшемдегі қол қойылған бүтін сандарды эмуляциялау үшін пайдалануға болады, бірақ бұл биттік операцияларды егжей-тегжейлі білуді талап етеді. JDK 8-де қолтаңбасыз бүтін сан түрлеріне қолдау көрсетілді, бірақ қолтаңбасыз байттар үшін емес және Java тілінде қолдау жоқ.

Оператордың жүктемесі

Java пайдаланушы анықтаған операторларды қолдамайтыны үшін сынға ұшырады. Операторды жүктеу оқымдылықты жақсартады, сондықтан оның болмауы Java кодын, әсіресе математикалық нысандарды бейнелейтін сыныптар үшін, мысалы, күрделі сандар мен матрицалар үшін, оқымсыз етеді. Java-да тек бір ғана сандық емес оператор бар: + және += - тізбекті біріктіру үшін. Алайда, бұл StringBuilder инстанцияларын құру үшін кодты шығаратын компилятормен іске асырылады. Пайдаланушы анықтаған оператор жүктемесін жасау мүмкін емес.

Құрама құн түрлері

Java-да құрама мәндер типтері жоқ, мысалы C-дегі structs, сілтемелер арқылы жанама емес, тікелей өңделетін деректер жиынтығы. Кейде мән түрлері сілтемелері бар сыныптардан жылдам және кішірек болуы мүмкін. Мысалы, Java HashMap HashMap сілтемелерінің массиві ретінде іске асырылады. Кіру объектілері, олар өз кезегінде кілт пен мән объектілеріне сілтемелерді қамтиды. Бір нәрсені іздеу екі рет сілтеме жасауды қажет етеді. Егер Entry мәні түрі болса, массив кілт-маңыз жұптарын тікелей сақтай алады, бірінші жанама жолды жояды, сілтеме жергіліктілігін арттырады және жадының пайдаланылуын және үйінді бөлшектеуін азайтады. Сонымен қатар, егер Java жалпы примитивті типтерді қолдайтын болса, кілттер мен мәндер массивте тікелей сақталуы мүмкін, бұл екі деңгейдің де жанамалығын жояды.

Үлкен массивтер

Java 231 элементтен тұратын массивтерді қолдамайтыны үшін сынға ұшырады (шамамен 2,1 миллиард) немесе одан да көп элементтер. Бұл тілдің шектеулілігі; Java Language Specification, Section 10.4, былай дейді: Массивтер int мәндерімен индекстелуі керек. Үлкен массивтерді қолдау JVM-ге өзгерістер енгізуді талап етеді. Бұл шектеулер өздерін 2 миллиард элементпен шектелген коллекциялар мен 2 ГБ-дан үлкен үздіксіз файл сегменттерін жад картасына орналастыру мүмкін еместігі сияқты салаларда көрсетеді. Java-да (оның 2D массивтерінен тыс) көп өлшемді массивтер (бірден-бір жанама жолмен қол жетімді жад блоктары) жоқ, бұл ғылыми және техникалық есептеулер үшін өнімділікті шектейді.

Примитивтер мен массивтерді интеграциялау

Массивтер мен примитивтер ерекше және оларға сыныптардан бөлек қарау керек. Бұл сынға ұшырады, өйткені жалпы мақсаттағы кітапханаларды құру кезінде көптеген функциялардың нұсқаларын қажет етеді.

Паралельдік

Пер Бринч Хансен 1999 жылы Java-ның жалпы параллельділікті іске асыруы, әсіресе мониторлар қауіпсіз және сенімді параллельді бағдарламалау үшін қажетті кепілдіктер мен күш қолдануды қамтамасыз етпейді деп мәлімдеді. Бағдарламашы жобалау мен кодтау конвенцияларын орната алады, ал компилятор оларды орындауға тырыса алмайды, сондықтан бағдарламашы бейхабардан қауіпсіз емес немесе сенімді емес кодты жаза алады.

Сериялау

Java-да объектіні сериалдастыру механизмі бар, онда объект өзінің және оның өрістері туралы типтік ақпаратпен бірге оның дерек өрістерін қамтитын байттар тізбегі ретінде бейнеленуі мүмкін. Объект сериалданғаннан кейін, оны кейіннен сериядан шығару мүмкін; яғни, оның деректерін білдіретін типтік ақпарат пен байттарды объектіні жадыда қайта құру үшін пайдалануға болады. Бұл өте қауіпті теориялық және нақты қауіпсіздік қауіптерін тудырады.

Жылжымалы нүктелік арифметика

Java-ның жылжымалы нүктелік арифметикалық жүйесі негізінен IEEE 754 (Білік жылжымалы нүктелік арифметикалық стандарт) негізінде жасалса да, кейбір міндетті стандарттық мүмкіндіктер strictfp модификаторын қолданғанда да қолдау таппайды, мысалы, ерекшелік жалаушалары және бағытталған дөңгелектеулер. IEEE 754 анықтаған кеңейтілген дәлдік типтері (және көптеген процессорлар қолдайды) Java-да қолдау таппайды.

Тюпльдердің болмауы

Java туплилерді қолдамайды, нәтижесінде үшінші тараптың іске асырулары көбейеді, оларды бағдарламашы импорттап, өңдеуі керек.

Ламбда өрнектері

Java 8 lambda өрнектерін енгізгенге дейін, әдісті басқа әдіске параметр ретінде беру қиын болды.

Код пен аппараттық жабдық арасындағы абстрактілі байланыс

2008 жылы АҚШ Қорғаныс министрлігінің Бағдарламалық қамтамасыз ету технологиясын қолдау орталығы "Қорғаныс бағдарламалық қамтамасыз ету инженериясы журналында" Java-ның бірінші оқыту тілі ретінде жарамсыздығын талқылайтын мақала жариялады. Кемшіліктері студенттердің "бастапқы бағдарлама мен аппараттық жасайтын іс-әрекеттің арасындағы қарым-қатынасты сезінбеуі" және "жазылған нәрсенің орындалу уақытының құнын түсіну мүмкін еместігі, өйткені кез-келген әдіс шақырудың ақырында не орындалатынын білу өте қиын". 2005 жылы Джоэл Спольски өзінің "JavaSchools қауіптері" атты эссесінде Java-ны университеттердің оқу бағдарламасының тым көп көңіл бөлінген бөлігі ретінде сынға алды. Нед Батчелдер сияқты басқалар, Спольскийдің түсіндірмесі "субъективті жарнама" деп, оны түсіну қиын деп тапқан тілдің бөліктерін сынға алғандығымен келіспейді.

Өнер көрсету

2000 жылға дейін, HotSpot VM Java 1.3 бағдарламасында іске асырылғанда, оның жұмыс істеуіне көптеген сын-пікірлер болды. Java-ның оптимизацияланған кодпен салыстырмалы жылдамдықпен жұмыс істейтіндігі дәлелденді, ал қазіргі заманғы JVM-нің іске асырылуы жүйелі түрде ең жылдам тіл платформаларының бірі ретінде салыстырылады. Орындаушылық ерте нұсқалардан бері айтарлықтай жақсарды. JIT компиляторларының жергілікті компиляторларға қатысты өнімділігі кейбір оңтайландырылған сынақтарда өте ұқсас екені дәлелденді. Java байт кодын виртуалды машина орындаған кезде түсіндіруге болады немесе жүктеу кезінде немесе орындаған кезде компьютердің аппараттық жасақтамасында тікелей орындалатын жергілікті кодқа компиляциялауға болады. Интерпретация жергілікті орындауға қарағанда баяу, бірақ жүктеу уақытында немесе орындау уақытында компиляция бастапқы өнімділікке зиян тигізеді. Қазіргі заманғы JVM-дің барлық іске асырылуы компиляция әдісін қолданады, сондықтан бастапқы іске қосу уақытынан кейін өнімділік жергілікті кодқа ұқсас болады. Ойын дизайнері және бағдарламашы Джон Кармак 2005 жылы ұялы телефондарда Java туралы былай деп қорытындылады: "Ең үлкен мәселе Java өте баяу. Чиста CPU / жады / дисплей / байланыс деңгейінде, қазіргі заманғы көптеген ұялы телефондар Game Boy Advance-ке қарағанда әлдеқайда жақсы ойын платформалары болуы керек. Java-мен, көптеген телефондарда сіз 4,77 мГц (sic) IBM PC-нің бастапқы процессор қуатымен және барлық нәрсені бақылауға болады.

Қауіпсіздік

Java платформасы пайдаланушыға зиянды немесе нашар жазылған бағдарламалық жасақтамадан қорғау үшін "sandboxed" тәсілмен сенімсіз байт-кодты орындауға мүмкіндік беретін қауіпсіздік архитектурасын ұсынады. Бұл "sandboxing" функциясы зиянды бағдарламалық жасақтама пайдалана алатын платформа функциялары мен API-ге қол жеткізуді шектеу арқылы пайдаланушыны қорғауды көздейді, мысалы жергілікті файл жүйесіне немесе желіге кіру немесе кездейсоқ командаларды орындау. 2010 жылы Java, соның ішінде Oracle бағдарламаларын іске асыруда қолданылатын құмдық қор механизмдеріндегі қауіпсіздік кемшіліктерін нысанаға алған зиянды бағдарламалардың саны едәуір өсті. Бұл кемшіліктер сенім артпайтын кодтың құмдық қоршаудың шектеулерін айналып өтуіне мүмкіндік береді, бұл пайдаланушыны шабуылдарға ұшыратады. Қауіпсіздік жаңартулары арқылы ақаулар түзетілді, бірақ жаңартуларсыз компьютерлерде әлі де пайдаланылды. Сыншылар пайдаланушылар Java орнатуларын жаңартпайтынын, өйткені олар бар екенін немесе оларды қалай жаңарту керектігін білмейді деп болжайды. Көптеген ұйымдар пайдаланушылардың бағдарламалық жасақтаманы орнатуын шектейді, бірақ жаңартуларды іске қосуға баяу. Oracle компаниясы белгілі қауіпсіздік қателеріне қатысты жаңартуларды дереу ұсынбағаны үшін сынға ұшырады. Oracle Java 7-де кеңінен пайдаланылатын кемшіліктерге арналған жапсырманы шығарған кезде, Java 6 корпоративтік қолданбалар кеңінен қолданылғанға қарамастан, Oracle кемшіліктерге әсер етпейтінін мәлімдеген. 2007 жылы Марко Пистоя бастаған зерттеу тобы Java қауіпсіздік моделінің тағы бір маңызды кемшілігін анықтады, ол стек тексеруге негізделген. Қауіпсіздікке сезімтал ресурсқа қол жеткізген кезде қауіпсіздік менеджері шақыру стегінен жүретін кодты іске қосады, онда әрбір әдістің код базасының ресурсқа қол жеткізу құқығы бар екенін тексеру үшін. Бұл заңды, артықшылықты бағдарламаны басқа біреу өз билігін теріс пайдалану үшін алдаған кезде болатын, шатастырған орынбасарлық шабуылдарды болдырмау үшін жасалады. Аң-сезімін шатастырған орынбасар мәселесі - артықшылықтарды арттырудың ерекше түрі. Pistoia қауіпсіздікке сезімтал ресурсқа қол жеткізген кезде ресурсты алуға жауапты код енді стекте болмауы мүмкін екенін атап өтті. Мысалы, бұрын орындалған әдіс объект өрісінің қай ресурсты пайдалану керектігін анықтайтын мәнін өзгерткен болуы мүмкін. Бұл әдіс шақыруы тексерілген кезде стекте болмауы мүмкін. Кейбір рұқсаттар Java-ның AllPermission-мен теңестіріледі. Бұларға қазіргі қауіпсіздік менеджерін өзгерту рұқсаты (соны стек тексеруден айналып өту мүмкіндігі бар басқа бірмен ауыстыру), жеке класты жүктеушісін (ол AllPermission-ді зиянды класқа жүктеу кезінде оны байланыстыруды таңдай алады) және жеке рұқсат жасау рұқсаты (ол өзін AllPermission-ке теңдей қуатты деп жариялай алады) жатады. Бұл мәселелер Пистояның Java Security туралы екі кітабында баяндалған.

Параллельді қондырғылар

Java 7 бағдарламасына дейін Java-ның ескі нұсқаларын өшірмейді. Windows жүйесінде бір компьютерде Java бірнеше орнатуды көру кең тараған. Бірнеше орнатуға рұқсат етілді және оларды белгілі бір нұсқаларға, соның ішінде зиянды бағдарламаларға негізделген бағдарламалар пайдалана алады. Бұл мәселе Java 7 бағдарламасында шешілді: пайдаланушының рұқсатымен, орнатушы бұрынғы орнатуларды алып тастайды.

Автоматты жаңартулар

2014 жылдан бастап жалпы үшінші тарап құралдары (мысалы, Adobe Flash және Adobe Reader) қауіпсіздіктің осал жерлерін тексеруге жатады. Adobe және басқалар Windows-та автоматты жаңартуларға көшті. Бұларға пайдаланушының әрекеті қажет емес және қауіпсіздік мәселелерін пайдаланушылар немесе әкімшілер аз күш жұмсай отырып тез арада шешеді. 2015 жылдың қорытындысы бойынша Java 8 әлі де пайдаланушылардан Java-ны өздері жаңартуды талап етеді. Бірақ Windows-та тек әкімші құқықтары барлар ғана бағдарламалық жасақтаманы жаңарта алады. Windows Java жаңартушысы жиі пайдаланушы тіркелгісін басқаруды бұзатын жоғарылатуды шақырады: пайдаланушылар қандай таңдау жасамасын, олар әлі де "Java жаңарту керек" деген хабарды алады.

JIT-пен байланысты қауіпсіздік проблемалары және мүмкін пайдаланулар

JIT құрастыру негізінен орындалатын деректерді пайдаланады, сондықтан қауіпсіздік мәселелерін және мүмкін пайдалануларды тудырады.