2016-09-19 3 views
0

Я часто сталкиваюсь с ситуацией, когда хочу вернуть несколько значений из метода Java, и для этой цели не стоит создавать класс/объект. В моем конкретном текущем случае у меня есть несколько методов проверки ввода, которые вычисляют промежуточные результаты, которые я хотел бы повторно использовать в вызывающих.Лучший способ вернуть строку в качестве параметра в Java

Одно из решений заключается в том, чтобы передать новый список и применить метод к моим результатам, но это вводит в заблуждение, когда я знаю, что всегда будет одно значение для каждого параметра, который я хочу вернуть.

Самая распространенная такая ситуация - когда я хочу вернуть строку. Я могу передать в StringBuilder или StringBuffer, и метод заполнит это значение. Но по какой-то странной причине эти классы не предоставляют метод set() (кроме конструктора, который не является полезным для этой цели). Самое близкое, что я могу придумать, это myStringBuilder.replace(0, myStringBuilder.length(), myString), но это действительно уродливо и не ясно передает мои намерения. Поэтому я хотел бы расширить эти классы с помощью собственного класса утилиты, который добавляет метод set() (и внутренне использует replace), но эти классы объявляются final по какой-то странной причине, и я тоже не могу этого сделать.

Я что-то упустил? Есть ли какой-то предпочтительный способ делать то, что я хочу, - передавая в каком-то записываемом буфере строк, в который метод может поместить значение? Есть ли веская причина, что эти классы объявлены окончательными?

Примером такого метода может быть:

void foo(List<ObjectA> arg1, List<ObjectB> arg2, StringBuffer somethingInteresting, StringBuffer somethingElseInteresting) 

Я не хочу, чтобы заменить последние два параметра списка, если две строки не имеют никакого отношения семантически, потому что я накладывая семантику на который не сообщается четко. Я не хочу передавать два отдельных списка и ожидать, что каждый из них вернется с размером() из 1, потому что это снова не понятно вызывающему.

+1

вы можете поделиться ожидаемой сигнатурой методы? – sidgate

+0

Надеюсь, текущий текст станет более четким. Я имел в виду для любого заданного параметра, я ожидаю единственный результат, поэтому, передавая кучу списков, каждый из которых, как ожидается, будет иметь размер() 1 при возврате, вводит в заблуждение. – BobDoolittle

+0

Я добавил подпись метода и некоторый дополнительный уточняющий текст. – BobDoolittle

ответ

3

Проблема заключается в вашем сопротивлении созданию другого класса. Я не говорю, что ваш вопрос неверен, но если вы хотите вернуть кучу значений, и ваша функция знает принцип единой ответственности, то эти значения связаны. Поскольку они связаны, у вас будут другие вещи, которые хотят работать на них как на группу. Эти операции относятся к классу, который вы возвращаете.

Я никогда не жалел о создании класса для возвращения подобных значений.

Я никогда не сожалел о разделении класса, который возвратил два несвязанных значения.

Java пытается не просто сделать то, о чем вы пожалеете.

Кстати, чтобы ответить на вопрос напрямую, вы можете вернуть массив строк. Возвращаемое значение String [] и вернуть ему что-то вроде «new String [] {firstString, secondString, thirdString}», но, как я уже сказал, это неправильный путь для принятия вообще.

Вы МОЖЕТЕ создать изменяемую строку, как вы говорите, но есть очень веская причина, что они неизменяемы. Неизменность - это ключ к безопасности потоков - даже если вы не думаете, что используете много потоков, изменение значений под вами является проблемой. Языки с высокой степенью резьбы смещаются в сторону неизменности (функциональный стиль) - я бы не стал строить инфраструктуру, выходящую из нее.

+0

Спасибо. Семантически я не думаю, что передача в массиве сильно отличается от передачи в списке (хотя это более легкий вес) - в обоих случаях семантический порядок результатов неявна, что плохо. – BobDoolittle

+1

Да, передача массива или списка плохая, как я уже сказал, создать класс - желательно неизменный. Я просто пытался ответить на заданный вопрос. –

+1

Кроме того, пожалуйста, не мутируйте вещи, переданные вам, если это действительно не нужно делать. Это неожиданное поведение, которое следующий редактор легко пропустит. Вы действительно должны вернуть свои результаты в возвращаемом значении. Java не имеет «выходных» параметров по какой-либо причине - они всего лишь плохая идея. Разумеется, мутация бизнес-объекта с состоянием каким-то предсказуемым способом. –

0

Если вам не нравится с помощью myStringBuilder.replace(0, myStringBuilder.length(), myString), потому что его цель не ясна, вы можете использовать

myStringBuilder.setLength(0);  // clears the existing content 
    myStringBuilder.append(myString); // sets the new string 
+0

Я предполагаю, что я просто озадачен тем, почему класс не предоставил способ сделать это в первую очередь. Кажется, большой надзор. Возможно, (как предположил Билл К), это преднамеренно и предназначено для того, чтобы уволить людей от имитации возвращаемых параметров с ними :-) – BobDoolittle

+0

Я по-прежнему не вижу веских оснований для объявления финальных итогов этих классов, тем самым не позволяя никому расширить их функциональность , – BobDoolittle

+0

Финал - это в основном проблема скорости. Эти объекты используются так часто, что компилятор может сделать некоторые довольно большие увеличения скорости, потому что они являются окончательными. Помните - Java примерно в 2 раза медленнее, чем C, это невероятно быстро для языка, основанного на vm, который предлагает сборку мусора и не имеет указателей. Они ускорили все, что могли, чтобы это сделать. Они также могут обеспечить определенный уровень доверия - когда метод принимает/возвращает строку, вы можете доверять множеству допущений, если это не было окончательным - кто знает? Это может даже быть мутированием на событии таймера или что-то в этом роде!?! –

Смежные вопросы