Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Сравнение строк или указателей на строки?


Автор: Connie 12.10.2008, 10:18
В примерах SUN нашел такой код
Код

public void propertyChange(PropertyChangeEvent evt) {
        if ("progress" == evt.getPropertyName() ) {

http://java.sun.com/docs/books/tutorial/uiswing/examples/components/ProgressBarDemoProject/src/components/ProgressBarDemo.java

И хотя выдается предупреждение 
Цитата
Comparing String with == or !=
 сравнение работает. Но если я правильно понял вот эта строка "progress" идентична new String("progress"), а если так, то сравниваться должны указатели на объекты и сравнение не должно проходить.

Почему же в этом случае оно работает? Или же это предусмотренное отступление от объектной модели данных? Вроде String не примитивный тип?
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html

Я знаю, что строки надо сравнивать используя somestring.equals(otherstring)

Автор: Platon 12.10.2008, 10:28
возможно evt.getPropertyName() возвращает ссылку на константную строку, и при запуске программы "progress" и getPropertyName(), если getPropertyName() возвращает "progress", а не new String("progress"), то == или != будут работать.

Цитата(Connie @  12.10.2008,  11:18 Найти цитируемый пост)
Но если я правильно понял вот эта строка "progress" идентична new String("progress")

Нет неправильно понял.

Добавлено через 3 минуты и 48 секунд
Хотя, как я заметил хорошим тоном является следующий код:

Код

class PropertyTest {
    public static final String PROP_NAME = "prop.name";
}
// ....
public void propertyChange(PropertyChangeEvent evt) {
        if (PropertyTest.PROP_NAME == evt.getPropertyName() ) {
// ....

При формировании объекта PropertyChangeEvent также устанавливаем propertyName PropertyTest.PROP_NAME

Автор: Connie 12.10.2008, 11:01
Platon, то есть константы сравнивать можно именно потому, что компилятор создаст не два экземпляра "progress", а один?
Если так, то понятно smile
Цитата
Хотя, как я заметил хорошим тоном является следующий код:
Это понятно  smile но источник кода я не зря указал.

Автор: Platon 12.10.2008, 11:37
Цитата(Connie @  12.10.2008,  12:01 Найти цитируемый пост)
то есть константы сравнивать можно именно потому, что компилятор создаст не два экземпляра "progress", а один?

Верно.

Добавлено через 8 минут и 19 секунд
Цитата(Connie @  12.10.2008,  12:01 Найти цитируемый пост)
Это понятно  smile но источник кода я не зря указал.

Придется мириться и не плодить больше подобный код. В туториале подобный подход из-за того, что в SwingWorker так нехорошо сделали.

Автор: Connie 12.10.2008, 14:48
Тогда получается в обработчиках событий лучше использовать первый вариант, чем второй, т.к. сравнение указателей должно происходить быстрее, правильно?
Код

 public void actionPerformed(ActionEvent e) {
        String cmd = e.getActionCommand();
     
        // Handle each button.
//Это сравнение быстрее
        if (PROG_EXIT==e.getActionCommand()) {
            dispose();
            System.exit(0);
        }   
//А это медленнее
        else if (NEW_GR.equals(cmd)){
            addNewGroup();
        }

Верно?

Извините, что по всякой ерунде Вас достаю

Автор: Platon 12.10.2008, 16:30
Цитата(Connie @  12.10.2008,  15:48 Найти цитируемый пост)
сравнение указателей должно происходить быстрее, правильно?

абсолютно верно

Автор: ivg 12.10.2008, 18:31
Цитата(Connie @  12.10.2008,  17:48 Найти цитируемый пост)
Тогда получается в обработчиках событий лучше использовать первый вариант, чем второй

Нет.

Автор: Platon 12.10.2008, 19:09
Цитата(ivg @  12.10.2008,  19:31 Найти цитируемый пост)
Нет. 

ммм, а почему?

Автор: Connie 12.10.2008, 20:44
Вот давайте рассуждать
вначале создается константа
private final static String MY_COMMAND = "start_doing";

Потом у какого то элемента создается 
SomeUnit.addActionListener(some_where);
SomeUnit..setActionCommand(MY_COMMAND);

Это будет означать передачу объекту SomeUnit ссылки на MY_COMMAND, которая потом и будет сравниваться на идентичность с сама с собой
if (MY_COMMNAD==e.getActionCommand())
Вряд ли в этом экземпляре объекта будет создаваться копия объекта. Хотя вдруг будет?

И если я правильно понимаю то, как даются адреса объектам, то неверное совпадение может быть лишь в случае ссылки указывающей на null.

Разумеется если я забуду указать final, static то тогда возможны различные коллюзии. Но рассуждая так можно какое угодно ограничение придумать  smile 

Автор: Platon 12.10.2008, 21:46
Цитата(Connie @  12.10.2008,  21:44 Найти цитируемый пост)
Хотя вдруг будет?

Я полагаю, что может быть по-разному в разных реализациях JVM, хотя, возможно, это закреплено железно в спецификациях. Но в в JVM от Sun не создаются. 

НО если в официальном туториале они прибегают к подобного рода коду, то это можно считать обычной практикой.
Цитата(Connie @  12.10.2008,  21:44 Найти цитируемый пост)
Разумеется если я забуду указать final, static то тогда возможны различные коллизии.

непонятно о чем это.

Автор: ivg 12.10.2008, 21:48
Цитата(Platon @  12.10.2008,  22:09 Найти цитируемый пост)
ммм, а почему?

Код

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import javax.swing.JCheckBox;

public class Main {

    static final String cb_command = "Action_Command";

    public static void main(String[] args) throws Exception {
        JCheckBox cb = new JCheckBox("test");
        cb.setActionCommand(cb_command);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(cb);
        oos.flush();
        oos.close();
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
        JCheckBox newcb = (JCheckBox)ois.readObject();
        System.out.println(cb.getActionCommand() == newcb.getActionCommand());
        System.out.println(cb.getActionCommand().equals(newcb.getActionCommand()));
    }
}

Автор: Platon 16.10.2008, 13:17
Несмотря на то, что GUI с сериализацией сильно не дружат, пожалуй, придется согласиться.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)