Как можно передать объект методу
Перейти к содержимому

Как можно передать объект методу

  • автор:

Передача объектов в методы

Объекты допускается передавать методам в качестве параметров точно так же, как и примитивные значения. При этом объекты передаются по ссылке на них. Метод может изменять полученные значения. Самый важный вопрос здесь — а будут ли изменяться эти значения в вызвавшем методе? Если в метод передан объект — то будут, если же это примитивное значение — то нет. Почему так? Давайте рассмотрим на следующем примере.

Пример 1. Изменение переданных значений в методе

При запуске программы в стеке выделяется область памяти для метода main(). Там хранятся локальные переменные x и y. При вызове метода changePrimitives() в стеке выделяется еще одна область памяти, в которой создаются локальные переменные, а и b. Их значения хранятся там же. Если, а и b изменяются, это никак не влияет на переменные x и y — они хранятся в разных областях памяти.

Локальная объектная переменная box создается в стековой области памяти метода main(), но сам объект создается в куче. При вызове метода changeObject() передается не сам объект, а ссылка на него. Поэтому при изменении переменной о, в методе changeObject(), меняется объект находящийся куче. И эти изменения, естественно, видны в вызвавшем методе main():

public class Box < double width; double height; double depth; Box(double w, double h, double d) < width = w; height = h; depth = d; >>
public class TestDemo < /** * Изменение объекта * * @param box */ static void changeObject(Box box) < box.width *= 2; box.height /= 2; box.depth += 2; >/** * Изменение примитивных типов * * @param a * @param b */ static void changePrimitives(int a, int b) < a *= 2; b /= 2; >public static void main(String[] args) < Box box = new Box(5, 6, 7); int x = 10; int y = 10; System.out.println("x и y перед вызовом: " + x + " " + y); changePrimitives(x, y); System.out.println("x и y после вызова: " + x + " " + y); System.out.println("box перед вызовом: " + box.width + " " + box.height + " " + box.depth); changeObject(box); System.out.println("box после вызова: " + box.width + " " + box.height + " " + box.depth); >>
x и y перед вызовом: 10 10 x и y после вызова: 10 10 box перед вызовом: 5.0 6.0 7.0 box после вызова: 10.0 3.0 9.0

Объекты можно создавать в методе и возвращать их. Например, как показано в следующем примере:

Пример 2. Возврат объекта из метода
public class ReturnObject < int a; ReturnObject(int i) < a = i; >ReturnObject incrementByTen() < ReturnObject temp = new ReturnObject(a + 10); return temp; >public static void main(String[] args) < ReturnObject ob1 = new ReturnObject(2); ReturnObject ob2 = ob1.incrementByTen(); System.out.println("ob1.a: " + ob1.a); System.out.println("ob2.a: " + ob2.a); >>
  • Процедурное и объектно-ориентированное программирование
  • Принципы ООП
  • Классы и объекты
  • Конструктор
  • Ключевое слово this
  • Перегрузка
  • Стек и куча
  • Java varargs
  • Рекурсия
  • Сборщик мусора и метод finalize
  • Наследование
  • Ключевое слово super
  • Модификаторы доступа
  • Геттеры и сеттеры
  • Переопределение методов
  • Абстрактные классы и методы
  • Ключевое слово final
  • Задания

Передача объектов в методы

Объекты допускается передавать методам в качестве параметров точно так же, как и примитивные значения. При этом объекты передаются по ссылке на них. Метод может изменять полученные значения. Самый важный вопрос здесь — а будут ли изменяться эти значения в вызвавшем методе? Если в метод передан объект — то будут, если же это примитивное значение — то нет. Почему так? Давайте рассмотрим на следующем примере.

Пример 1. Изменение переданных значений в методе

При запуске программы в стеке выделяется область памяти для метода main(). Там хранятся локальные переменные x и y. При вызове метода changePrimitives() в стеке выделяется еще одна область памяти, в которой создаются локальные переменные, а и b. Их значения хранятся там же. Если, а и b изменяются, это никак не влияет на переменные x и y — они хранятся в разных областях памяти.

Локальная объектная переменная box создается в стековой области памяти метода main(), но сам объект создается в куче. При вызове метода changeObject() передается не сам объект, а ссылка на него. Поэтому при изменении переменной о, в методе changeObject(), меняется объект находящийся куче. И эти изменения, естественно, видны в вызвавшем методе main():

public class Box < double width; double height; double depth; Box(double w, double h, double d) < width = w; height = h; depth = d; >>
public class TestDemo < /** * Изменение объекта * * @param box */ static void changeObject(Box box) < box.width *= 2; box.height /= 2; box.depth += 2; >/** * Изменение примитивных типов * * @param a * @param b */ static void changePrimitives(int a, int b) < a *= 2; b /= 2; >public static void main(String[] args) < Box box = new Box(5, 6, 7); int x = 10; int y = 10; System.out.println("x и y перед вызовом: " + x + " " + y); changePrimitives(x, y); System.out.println("x и y после вызова: " + x + " " + y); System.out.println("box перед вызовом: " + box.width + " " + box.height + " " + box.depth); changeObject(box); System.out.println("box после вызова: " + box.width + " " + box.height + " " + box.depth); >>
x и y перед вызовом: 10 10 x и y после вызова: 10 10 box перед вызовом: 5.0 6.0 7.0 box после вызова: 10.0 3.0 9.0

Объекты можно создавать в методе и возвращать их. Например, как показано в следующем примере:

Пример 2. Возврат объекта из метода
public class ReturnObject < int a; ReturnObject(int i) < a = i; >ReturnObject incrementByTen() < ReturnObject temp = new ReturnObject(a + 10); return temp; >public static void main(String[] args) < ReturnObject ob1 = new ReturnObject(2); ReturnObject ob2 = ob1.incrementByTen(); System.out.println("ob1.a: " + ob1.a); System.out.println("ob2.a: " + ob2.a); >>
  • Процедурное и объектно-ориентированное программирование
  • Принципы ООП
  • Классы и объекты
  • Конструктор
  • Ключевое слово this
  • Перегрузка
  • Стек и куча
  • Java varargs
  • Рекурсия
  • Сборщик мусора и метод finalize
  • Наследование
  • Ключевое слово super
  • Модификаторы доступа
  • Геттеры и сеттеры
  • Переопределение методов
  • Абстрактные классы и методы
  • Ключевое слово final
  • Задания

Как можно передать объект методу

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

public class Program < public static void main(String[] args) < Person kate = new Person("Kate"); System.out.println(kate.getName()); // Kate changeName(kate); System.out.println(kate.getName()); // Alice >static void changeName(Person p) < p.setName("Alice"); >> class Person < private String name; Person(String name)< this.name = name; >public void setName(String name) < this.name = name; >public String getName() < return this.name; >>

Здесь в метод changeName передается объект Person, у которого изменяется имя. Так как в метод будет передаваться копия ссылки на область памяти, в которой находится объект Person, то переменная kate и параметр p метода changeName будут указывать на один и тот же объект в памяти. Поэтому после выполнения метода у объекта kate, который передается в метод, будет изменено имя с «Kate» на «Alice».

От этого случая следует отличать другой случай:

public class Program < public static void main(String[] args) < Person kate = new Person("Kate"); System.out.println(kate.getName()); // Kate changePerson(kate); System.out.println(kate.getName()); // Kate - изменения не произошло // kate хранит ссылку на старый объект >static void changePerson(Person p) < p = new Person("Alice"); // p указывает на новый объект p.setName("Ann"); >static void changeName(Person p) < p.setName("Alice"); >> class Person < private String name; Person(String name)< this.name = name; >public void setName(String name) < this.name = name; >public String getName() < return this.name; >>

В метод changePerson также передается копия ссылки на объект Person. Однако в самом методе мы изменяем не отдельные значения объекта, а пересоздаем объект с помощью конструктора и оператора new. В результате в памяти будет выделено новое место для нового объекта Person, и ссылка на этот объект будет привоена параметру p:

static void changePerson(Person p) < p = new Person("Alice"); // p указывает на новый объект p.setName("Ann"); // изменяется новый объект >

То есть после создания нового объекта Person параметр p и переменная kate в методе main будут хранить ссылки на разные объекты. Переменная kate, которая передавалась в метод, продолжит хранить ссылку на старый объект в памяти. Поэтому ее значение не меняется.

Как можно передать объект методу

Объявление для метода или конструктора объявляет число и тип параметров за тот метод или конструктора. Например, следующее является методом, который вычисляет ежемесячные платежи за внутренний заем, основанный на количестве ссуды, процентной ставки, длины ссуды (число периодов), и будущее значение ссуды:

public double computePayment( double loanAmt, double rate, double futureValue, int numPeriods) < double interest = rate / 100.0; double partial1 = Math.pow((1 + interest), - numPeriods); double denominator = (1 - partial1) / interest; double answer = (-loanAmt / denominator) - ((futureValue * partial1) / denominator); return answer; >

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

Отметьте: Параметры обращаются к списку переменных в объявлении метода. Параметрами являются фактические значения, которые передают в том, когда метод вызывается. Когда Вы вызываете метод, используемые параметры должны соответствовать параметры объявления в типе и порядке.

Типы параметра

Можно использовать любой тип данных для параметра метода или конструктора. Это включает примитивные типы данных, те, которые удваиваются, плавания, и целые числа, как Вы видели в computePayment метод, и типы справочных данных, такие как объекты и массивы.

Вот пример метода, который принимает массив как параметр. В этом примере метод создает новое Polygon возразите и инициализирует это от массива Point объекты (принимают это Point class, который представляет x, y координата):

public Polygon polygonFrom(Point[] corners) < // method body goes here >

Отметьте: язык программирования Java не позволяет Вам передавать методы в методы. Но можно передать объект в метод и затем вызвать методы объекта.

Произвольное число Параметров

Можно использовать конструкцию, названную varargs, чтобы передать произвольное число значений к методу. Вы используете varargs, когда Вы не знаете, сколько из определенного типа параметра передадут к методу. Это — ярлык на создание массива вручную (предыдущий метод, возможно, использовал varargs, а не массив).

Чтобы использовать varargs, Вы следуете за типом последнего параметра замещающим знаком (три точки. ), затем пространство, и название параметра. Метод можно тогда вызвать с любым числом того параметра, включая ни один.

public Polygon polygonFrom(Point. corners) < int numberOfSides = corners.length; double squareOfSide1, lengthOfSide1; squareOfSide1 = (corners[1].x - corners[0].x) * (corners[1].x - corners[0].x) + (corners[1].y - corners[0].y) * (corners[1].y - corners[0].y); lengthOfSide1 = Math.sqrt(squareOfSide1); // more method body code follows that creates and returns a // polygon connecting the Points >

Можно видеть что в методе, corners обрабатывается как массив. Метод можно вызвать или с массивом или с последовательностью параметров. Код в теле метода обработает параметр как массив в любом случае.

Вы будете обычно видеть varargs с методами печати; например, это printf метод:

public PrintStream printf(String format, Object. args)

позволяет Вам печатать произвольное число объектов. Это можно вызвать как это:

System.out.printf("%s: %d, %s%n", name, idnum, address);
System.out.printf("%s: %d, %s, %s, %s%n", name, idnum, address, phone, email);

или со все же различным числом параметров.

Названия параметра

Когда Вы объявляете параметр к методу или конструктору, Вы обеспечиваете имя для того параметра. Это имя используется в пределах тела метода, чтобы обратиться к переданному — в параметре.

Имя параметра должно быть уникальным в его контексте. Это не может быть то же самое как имя другого параметра для того же самого метода или конструктора, и это не может быть имя локальной переменной в пределах метода или конструктора.

У параметра может быть то же самое имя как одно из полей class. Если это верно, параметр говорится тени поле. Поля затенения могут сделать Ваш код трудным читать и традиционно используются только в пределах конструкторов и методов, которые устанавливают определенное поле. Например, рассмотрите следующий Circle class и setOrigin метод:

public class Circle < private int x, y, radius; public void setOrigin(int x, int y) < . >>

Circle У class есть три поля: x , y , и radius . setOrigin у метода есть два параметра, у каждого из которых есть то же самое имя как одно из полей. Каждые тени параметра метода поле, которое совместно использует его имя. Так используя простые имена x или y в пределах тела метода обращается к параметру, не к полю. Чтобы получить доступ к полю, следует использовать полностью определенное имя. Это будет обсуждено позже в этом уроке в разделе, названном «Используя this Ключевое слово.»

Передача Примитивных Параметров Типа данных

Примитивные параметры, такой как int или a double , передаются в методы значением. Это означает, что любые изменения к значениям параметров существуют только в рамках метода. Когда метод возвращается, параметров не стало, и любые изменения им теряются. Вот пример:

public class PassPrimitiveByValue < public static void main(String[] args) < int x = 3; // invoke passMethod() with // x as argument passMethod(x); // print x to see if its // value has changed System.out.println("After invoking passMethod, x = " + x); >// change parameter in passMethod() public static void passMethod(int p) < p = 10; >>

Когда Вы выполняете эту программу, вывод:

After invoking passMethod, x = 3

Передача Параметров Типа Справочных данных

Параметры типа справочных данных, такие как объекты, также передает в методы значение. Это означает, что, когда метод возвращается, переданный — в ссылке все еще ссылается на тот же самый объект как прежде. Однако, значения полей объекта могут быть изменены в методе, если у них есть надлежащий уровень доступа.

Например, рассмотрите метод в произвольном class, который перемещается Circle объекты:

public void moveCircle(Circle circle, int deltaX, int deltaY) < // code to move origin of // circle to x+deltaX, y+deltaY circle.setX(circle.getX() + deltaX); circle.setY(circle.getY() + deltaY); // code to assign a new // reference to circle circle = new Circle(0, 0); >

Позвольте методу быть вызванным с этими параметрами:

moveCircle(myCircle, 23, 56)

В методе, circle первоначально обращается к myCircle . Метод изменяет x и y координаты объекта это circle ссылки (то есть, myCircle ) 23 и 56, соответственно. Эти изменения сохранятся, когда метод возвратится. Затем circle присваивается ссылка на новое Circle объект с x = y = 0 . У этого перевода по службе нет никакого постоянства, однако, потому что в ссылке передало значение и не может измениться. В пределах метода, объект, которым указывают circle изменился, но, когда метод возвращается, myCircle все еще ссылается на то же самое Circle возразите как, прежде, чем метод вызвали.

Ваше использование этой страницы и всего материала на страницах под «Учебным баннером» Java подвергается этим официальным уведомлениям.

Авторское право © 1995, 2012 Oracle и/или его филиалы. Все права защищены.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *