Предположим, у вас есть класс объекта с тремя целыми полями , которые вы хотите изменить, одинаково одним способом.int vs Integer vs пользовательский класс для достижения эффективного прохождения по эталонному поведению в Java
Давайте сохраним это просто и скажем все, что метод делает, добавляет 1 к переданному ему параметру.
То есть, желаемое поведение является то, что к тому времени, метод завершенного, соответствующее поле увеличилось на 1.
Это невозможно достичь в Java с помощью примитивного типа «ИНТ» для тех, поля.
Я знаю о том, что Java «всегда» передается по значению, а не проходит по ссылке - и - я слышал, как в сети существует одна из причин, по которой существует класс Integer, а также другой объект «wrapper» "классы для обычных примитивных типов, таких как int и double.
Отправка объекта в качестве аргумента в метод должна теоретически предоставлять способ [эффективно, если не технически] передавать по ссылке, поскольку переданное значение, предположительно, является значением ссылки на объект , Очень сложно. НО - и это то, куда приходит мое раздражение. Я попытался достичь этой очень простой задачи, передав аргумент Integer вместо int, и желаемое поведение все еще не было выполнено. 1 не добавлено в соответствующее поле.
И все же, когда я создал свой собственный объект, состоящий из одного поля, значение int и передал экземпляр этого объекта в качестве аргумента соответствующему методу, который просто добавит 1 к переданному параметру , фактически было выполнено желаемое поведение. 1 был добавлен в соответствующее поле.
Таким образом, вопросы, связанные с этим запросом, - это действительно необходимо, чтобы создать собственный собственный класс, чтобы нести простое целое значение каждый раз, когда я хочу достичь этого желаемого поведения? Может ли существующий инструмент, предоставляемый Java, Integer, действительно не выполнять эту простую задачу?
Вместо того, чтобы иметь один хороший, аккуратный метод обработки всех трех гипотетических целочисленных полей, упомянутых в начале, я чувствовал себя вынужденным (в отдельном, аналогичном проекте, который в конечном итоге спровоцировал эту линию мышления) сделать отдельный метод соответствующие каждому из трех полей, с по существу одинаковым точным кодом в каждом из них. Это кажется очень неэффективным.
На первый взгляд может показаться сложным, чтобы написать три аналогичных метода вместо одного, но пояснить, почему это меня смущает - представьте, вместо объекта с тремя целыми полями, как я уже сказал, говорят: , я не знаю, четыре тысячи. Было бы гораздо лучше написать одну вещь, чтобы выполнить одно и то же поведение, вместо того, чтобы копировать и вставлять (и менять любые маленькие биты) четыре тысячи раз.
Таким образом, я предполагаю, что конечный вопрос: Почему Integer не функционирует разумным образом? Какой смысл обертывать примитив в объекте вообще, если он даже не помогает выполнить что-то такое простое? Я пропустил что-то простое о том, как заставить Integer функционировать желаемым образом? (Надеюсь, что так). Ответ кажется закрытым, но в ярости недоступным, поскольку «RInteger» создает желаемое поведение, но «Integer» этого не делает.
Весь исходный код, который я использовал при попытке выяснить, как построить этот кропотливый вопрос, приведен ниже.
package r9mp;
import javax.swing.SwingUtilities;
public class RefTest2 {
//[main m]
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
new RefTest2();
}
});
}
//[fields]
int i;
Integer I;
RInteger RI;
//[constr]
public RefTest2(){
intTest();
IntegerTest();
RIntegerTest();
display();
}
//[methods]
private void intTest(){
i = 100;
intMethod(i);
}
private void IntegerTest(){
I = 100; //boxing? auto?
IntegerMethod(I);
I = 100; //just in case.
IntegerMethod2(I);
}
private void RIntegerTest(){
RI = new RInteger(100);
RIntegerMethod(RI);
}
private void intMethod(int ipar){
ipar = ipar + 1;//no change. expected.
}
private void IntegerMethod(Integer IPar){
IPar = IPar + 1;//no change. frustrating.
pln("From inside IntegerMethod: IPar = " + IPar);
pln("From inside IntegerMethod: I = " + I);
}
private void IntegerMethod2(Integer IPar){
IPar = new Integer(IPar+1);//still no change. there are no set methods for Integer, or I'd try them.
}
private void RIntegerMethod(RInteger riPar){
riPar.value = riPar.value + 1;
}
private void display(){
pln(
"Display... \n" +
"i: " + i + "\n" +
"I: " + I + "\n" +
"RI: " + RI + "\n" +
"--------"
);
}
private void pln(){
pln("");
}
private void pln(String s){
System.out.println(s);
}
//[internal class]
private class RInteger{
int value;
public RInteger(int v){
value = v;
}
public String toString(){
return ""+value;
}
}
}
Привет Райан, вы, кажется, использует свой класс Java 'RefTest2' странным образом. Как правило, класс будет иметь поля, которые обновляются. Поэтому не имеет значения, передаются ли переменные метода setter по ссылке или передаются по значению, потому что мы используем их только как поля для чтения для передачи информации. –
Если вы хотите написать метод с побочными эффектами (что уже довольно плохо), используйте массив. Довольно очевидное обходное решение. – Tom
Поскольку 'Integer' является неизменным, он в основном ведет себя так же, как' int' делает с точки зрения передачи его методам и его изменения. Вы не можете изменить значение внутри 'Integer', вы можете создавать только новый экземпляр, который затем переопределяет переданное значение и оставляет прежнюю ссылку в такте. – luk2302