Статическая привязка в Java [duplicate]

Сценарий, который я написал для моего GitBash . Выполняет следующее:

  • По умолчанию тянет из источника для всех ветвей, которые настроены для отслеживания начала координат, позволяет при желании указать другой пульт.
  • Если ваша текущая ветка находится в грязном состоянии, тогда он задерживает ваши изменения и попытается восстановить эти изменения в конце.
  • Для каждой локальной ветви, которая настроена для отслеживания удаленной ветки, будет: git checkout branch git pull origin
  • Наконец, вернем вас в исходное состояние ветви и восстановления.

** Я использую это, но не тестировал полностью, используйте на свой страх и риск. Пример этого скрипта в файле .bash_alias здесь .

    # Do a pull on all branches that are tracking a remote branches, will from origin by default.
    # If current branch is dirty, will stash changes and reply after pull.
    # Usage: pullall [remoteName]
    alias pullall=pullAll
    function pullAll (){
     # if -h then show help
     if [[ $1 == '-h' ]]
    then
      echo "Description: Pulls new changes from upstream on all branches that are tracking remotes."
      echo 
      echo "Usage: "
      echo "- Default: pullall"
      echo "- Specify upstream to pull from: pullall [upstreamName]"
      echo "- Help: pull-all -h"
    else

     # default remote to origin
     remote="origin"
     if [ $1 != "" ]
     then
       remote=$1
     fi

     # list all branches that are tracking remote
     # git branch -vv : list branches with their upstreams
     # grep origin : keep only items that have upstream of origin
     # sed "s/^.."... : remove leading *
     # sed "s/^"..... : remove leading white spaces
     # cut -d" "..... : cut on spaces, take first item
     # cut -d splits on space, -f1 grabs first item
     branches=($(git branch -vv | grep $remote | sed "s/^[ *]*//" | sed "s/^[ /t]*//" | cut -d" " -f1))

     # get starting branch name
     startingBranch=$(git rev-parse --abbrev-ref HEAD)

     # get starting stash size
     startingStashSize=$(git stash list | wc -l)

     echo "Saving starting branch state: $startingBranch"
     git stash

     # get the new stash size
     newStashSize=$(git stash list | wc -l)

     # for each branch in the array of remote tracking branches
     for branch in ${branches[*]}
     do
       echo "Switching to $branch"
       git checkout $branch

       echo "Pulling $remote"
       git pull $remote

     done

     echo "Switching back to $startingBranch"
     git checkout $startingBranch

     # compare before and after stash size to see if anything was stashed
     if [ "$startingStashSize" -lt "$newStashSize" ]
     then
       echo "Restoring branch state"
       git stash pop
     fi
    fi
    }

56
задан nbro 26 October 2015 в 22:02
поделиться

6 ответов

Из Javarevisited blog post :

Вот несколько важных различий между статическим и динамическим связыванием:

  1. Статическое связывание в Java возникает во время компиляции, тогда как динамическое связывание происходит во время выполнения.
  2. private, final и static методы и переменные используют статическое связывание и связаны с компилятором, тогда как виртуальные методы связаны во время выполнения на основе объекта времени выполнения.
  3. Статическая привязка использует Type (class в Java) информацию для привязки, тогда как динамическое связывание использует объект для разрешения привязки.
  4. Перегруженные методы связаны с использованием статического связывания, тогда как переопределенные методы связаны с использованием динамического связывания во время выполнения.

Вот пример, который поможет вам понять как статическую, так и динамическую привязку в Java.

Пример статической привязки в Java

public class StaticBindingTest {  
    public static void main(String args[]) {
        Collection c = new HashSet();
        StaticBindingTest et = new StaticBindingTest();
        et.sort(c);
    }
    //overloaded method takes Collection argument
    public Collection sort(Collection c) {
        System.out.println("Inside Collection sort method");
        return c;
    }
    //another overloaded method which takes HashSet argument which is sub class
    public Collection sort(HashSet hs) {
        System.out.println("Inside HashSet sort method");
        return hs;
    }
}

Вывод: метод сортировки внутри коллекции

Пример динамического связывания в Java

public class DynamicBindingTest {   
    public static void main(String args[]) {
        Vehicle vehicle = new Car(); //here Type is vehicle but object will be Car
        vehicle.start(); //Car's start called because start() is overridden method
    }
}

class Vehicle {
    public void start() {
        System.out.println("Inside start method of Vehicle");
    }
}

class Car extends Vehicle {
    @Override
    public void start() {
        System.out.println("Inside start method of Car");
    }
}

Выход: метод внутреннего запуска автомобиля

71
ответ дан Andrew 20 August 2018 в 18:33
поделиться
  • 1
  • 2
    Пожалуйста, дайте кредит в следующий раз, когда он должен – Don Larynx 5 April 2015 в 23:56
  • 3
    Я до сих пор не понимаю разницы, – technazi 12 October 2016 в 18:29
  • 4
    Статическое связывание @technazi просто смотрит на тип (что когда-либо было до равных, например Collection c = new HashSet (), поэтому он будет рассматриваться как только объект коллекции, если он является хешетом). Связывание Dyanmic учитывает фактический объект (что после равенства, так что он фактически распознает его HashSet). – Mark 19 April 2017 в 10:39

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

Ваш вызов привязан к классу Animal во время компиляции, потому что вы указали тип. Если вы передадите эту переменную в другой метод где-то в другом месте, никто не узнает (кроме вас, потому что вы ее написали), каков будет фактический класс. Единственный ключ - объявленный тип Animal.

-3
ответ дан Aaron 20 August 2018 в 18:33
поделиться
  • 1
    Не правда. Компилятор выполнил бы то же самое решение, если бы вы выполняли вызов по интерфейсу. – Hot Licks 26 September 2013 в 01:57
  • 2
    @HotLicks Точное решение, как? Если вы компилируете класс для вызова метода foo (String str) на интерфейсе, компилятор не может знать во время компиляции, в какой класс должен быть вызван метод foo (String str). Только во время выполнения вызов метода может быть привязан к конкретной реализации класса. – Aaron 26 September 2013 в 02:21
  • 3
    Но статическое связывание с сигнатурой конкретного метода все равно будет происходить. Компилятор по-прежнему будет выбирать callEat (Animal) через callEat (Собака). – Hot Licks 26 September 2013 в 02:25
  • 4
    @HotLicks Конечно, но это не вопрос, на который я ответил. Возможно, это меня вводило в заблуждение: D я сравнил ее с вызовом на интерфейсе, чтобы подчеркнуть, что во время компиляции компилятор не может знать, действительно ли вы создали экземпляр другого подкласса / реализации или нет. – Aaron 26 September 2013 в 02:27
  • 5
    Фактически, во время компиляции компилятор может (в этом случае) очень легко знать, что «a» это собака. На самом деле, вероятно, это должно пройти до некоторой длины, чтобы «забыть». что. – Hot Licks 26 September 2013 в 02:30

Компилятор знает только, что тип «a» - Animal; это происходит во время компиляции, из-за чего оно называется статическим привязкой (перегрузка метода). Но если это динамическое связывание, это вызовет метод класса Dog. Ниже приведен пример динамической привязки.

public class DynamicBindingTest {

    public static void main(String args[]) {
        Animal a= new Dog(); //here Type is Animal but object will be Dog
        a.eat();       //Dog's eat called because eat() is overridden method
    }
}

class Animal {

    public void eat() {
        System.out.println("Inside eat method of Animal");
    }
}

class Dog extends Animal {

    @Override
    public void eat() {
        System.out.println("Inside eat method of Dog");
    }
}

Выход: метод внутрижильного использования собаки

3
ответ дан Arvindh Mani 20 August 2018 в 18:33
поделиться
  • 1
    Разве это не приведет к ошибке компиляции, такой как «Нельзя ссылаться на нестатический класс / метод из статического контекста»? Я всегда смущен этим, имея в виду, что основной является статичным. Заранее спасибо. – Amnor 14 December 2016 в 10:02

Существуют три основных различия между статическим и динамическим связыванием при разработке компиляторов и способах переноса переменных и процедур в среду выполнения. Эти различия заключаются в следующем:

Статическое связывание: при статической привязке обсуждаются три следующие проблемы:

  • Определение процедуры
  • Объявление имени (переменная и т. д.)
  • Область декларации

Динамическое связывание. Три проблемы, возникающие в динамической привязке, следующие:

  • Активация процедуры
  • Связывание имени
  • Срок службы привязки
1
ответ дан hexpheus 20 August 2018 в 18:33
поделиться

Подключение вызова метода к телу метода называется привязкой. Как сказал Маулик, «Static binding использует информацию типа (класс в Java) для привязки, тогда как динамическое связывание использует Object для разрешения привязки». Итак, этот код:

public class Animal {
    void eat() {
        System.out.println("animal is eating...");
    }
}

class Dog extends Animal {

    public static void main(String args[]) {
        Animal a = new Dog();
        a.eat(); // prints >> dog is eating...
    }

    @Override
    void eat() {
        System.out.println("dog is eating...");
    }
}

Изменит результат: собака ест ... потому что использует ссылку на объект, чтобы найти, какой метод использовать. Если мы изменим приведенный выше код на это:

class Animal {
    static void eat() {
        System.out.println("animal is eating...");
    }
}

class Dog extends Animal {

    public static void main(String args[]) {

        Animal a = new Dog();
        a.eat(); // prints >> animal is eating...

    }

    static void eat() {
        System.out.println("dog is eating...");
    }
}

Это произведет: животное ест ... потому что это статический метод, поэтому он использует Type (в данном случае Animal), чтобы решить, статический метод для вызова. Помимо статических методов, частные и конечные методы используют один и тот же подход.

8
ответ дан realPK 20 August 2018 в 18:33
поделиться

С помощью статического метода в родительском и дочернем классах: Static Binding

public class test1 {   
    public static void main(String args[]) {
        parent pc = new child(); 
        pc.start(); 
    }
}

class parent {
    static public void start() {
        System.out.println("Inside start method of parent");
    }
}

class child extends parent {

    static public void start() {
        System.out.println("Inside start method of child");
    }
}

// Output => Inside start method of parent

Динамическое связывание:

public class test1 {   
    public static void main(String args[]) {
        parent pc = new child();
        pc.start(); 
    }
}

class parent {
   public void start() {
        System.out.println("Inside start method of parent");
    }
}

class child extends parent {

   public void start() {
        System.out.println("Inside start method of child");
    }
}

// Output => Inside start method of child
0
ответ дан Soudipta Dutta 20 August 2018 в 18:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: