Java String срещу аргумент на командния ред

Защо се случва, че аргумент на командния ред, предаден на Java клас, изглежда автоматично екраниран, докато в инстанциран String обект символът за екраниране () привидно се игнорира.

Например, ако започнете с низ като този:

SELECT * FROM my_table WHERE my_col like 'ABC_\' ESCAPE '\'

И се опитвам да го пусна през прост клас като този:

public class EscapeTest {
    public static void main (String[] args) {
        String str = "SELECT * FROM my_table WHERE " 
                     + "my_col like 'ABC_\' ESCAPE '\'";
        System.out.println("ARGS[0]: "+args[0]);
        System.out.println("STR: "+str);
}
}

и подавам командата "SELECT" по-горе като аргумент на командния ред, получавам резултат, който изглежда така:

ARGS[0]: SELECT * FROM my_table WHERE my_col like 'ABC_\' ESCAPE '\'

STR: SELECT * FROM my_table WHERE my_col like 'ABC_' ESCAPE ''

Ако погледна стойността на ARGS[0] в програмата за отстраняване на грешки на Eclipse, виждам, че наклонените черти са екранирани. Защо това се случва? Мисля, че е доста трудно да се предвиди.


person Jason Holmberg    schedule 22.07.2011    source източник


Отговори (1)


Съдържанието на вашия низ str не съдържа обратни наклонени черти. Те се обработват от Java компилатора, който разбира екраниращите последователности на низовите литерали на Java.

Процесорът на командния ред вероятно не прави това - той не третира обратно наклонената черта специално по никакъв начин, въпреки че това ще зависи от вашата обвивка. (В повечето обвивки на Unix ще третира обратната наклонена черта по различен начин. Предполагам, че сте на Windows.)

И така, вашият аргумент от командния ред има обратни наклонени черти. Те не са екранирани от изпълняващия Java процес - те просто са „там“ в низа.

Сега изглежда, че дебъгерът избягва низа, когато ви го показва, така че да можете да виждате неща като раздели и нови редове. Важно е да разберете, че това е просто начинът, по който програмата за отстраняване на грешки показва низа - няма такова нещо като "изход" в самия низ на Java.

РЕДАКТИРАНЕ: Според коментар:

За да изразите този низ в изходния код на Java, трябва да избегнете обратните наклонени черти:

String str = "SELECT * FROM my_table WHERE my_col like 'ABC_\\' ESCAPE '\\'"; 

Обратните наклонени черти трябва да бъдат екранирани, тъй като обратната наклонена черта е екраниращият знак в низовите литерали на Java.

person Jon Skeet    schedule 22.07.2011
comment
Вероятно за изясняване на вашия правилен отговор: за да изразите този низ в изходния код на Java, вие наистина трябва да напишете: String str = "SELECT * FROM my_table WHERE my_col like 'ABC_\\' ESCAPE '\\'"; Обратните наклонени черти трябва да бъдат екранирани, тъй като те са символът за екраниране в литерал на низов източник на Java. - person Sean Owen; 22.07.2011
comment
Всъщност изпълнявам това на Mac, така че ефективно Unix. Изпълнението в Eclipse и от и терминал (unix CLI) води до същия резултат. Разбирам за избягването на символа за избягване в инстанцията на String в източника на Java, просто се опитвах да покажа сравнение едно към едно. - person Jason Holmberg; 23.07.2011
comment
@Джейсън: Ако работите в терминала, бих очаквал черупката да се справи с обработката на обратната наклонена черта като символ за изход. Бихте ли показали своя точни команден ред? (Влизайки в Eclipse, мога да разбера, че е малко по-различен.) - person Jon Skeet; 23.07.2011
comment
@Jon: Ето моят точен команден ред: java org.jason.string.EscapeTest SELECT * FROM my_table WHERE my_col като 'ABC_\' ESCAPE '\' - person Jason Holmberg; 23.07.2011
comment
@Jon: Ето точния команден ред java org.jason.string.EscapeTest "SELECT * FROM my_table WHERE my_col like 'ABC_\' ESCAPE '\'" - person Jason Holmberg; 23.07.2011
comment
@Jason: Трябва да са двойните кавички, които избягват обратните наклонени черти да бъдат цитирани. Мислех, че само единични кавички правят това, но никога не мога да си спомня подробностите за избягването на bash... - person Jon Skeet; 23.07.2011