Разница между статическим и окончательным?

174

Я всегда путаю между staticи finalключевые слова в Java .

Насколько они разные ?

TechnoCorner
источник

Ответы:

238

Ключевое слово static может использоваться в 4 сценариях

  • статические переменные
  • статические методы
  • статические блоки кода
  • статический вложенный класс

Давайте сначала посмотрим на статические переменные и статические методы.

Статическая переменная

  • Это переменная, которая принадлежит классу, а не объекту (экземпляру).
  • Статические переменные инициализируются только один раз, в начале выполнения. Эти переменные будут инициализированы в первую очередь, до инициализации любых переменных экземпляра.
  • Одна копия для общего доступа всем экземплярам класса.
  • Статическая переменная может быть доступна напрямую по имени класса и не нуждается в каком-либо объекте.
  • Синтаксис: Class.variable

Статический метод

  • Это метод, который принадлежит классу, а не объекту (экземпляру).
  • Статический метод может получить доступ только к статическим данным. Он не может получить доступ к нестатическим данным (переменным экземпляра), если не имеет / создает экземпляр класса.
  • Статический метод может вызывать только другие статические методы и не может вызывать нестатический метод из него, если он не имеет / создает экземпляр класса.
  • Статический метод может быть доступен напрямую по имени класса и не нуждается в каком-либо объекте.
  • Синтаксис: Class.methodName()
  • Метод статического не может ссылаться на thisили superключевые слова в любом случае.

Статический класс

Java также имеет «статические вложенные классы». Статический вложенный класс - это просто класс, который неявно не имеет ссылки на экземпляр внешнего класса.

Статические вложенные классы могут иметь методы экземпляра и статические методы.

В Java нет такого понятия, как статический класс верхнего уровня.

Примечание:

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

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

  • finalКласс не может иметь подклассов. Это сделано из соображений безопасности и эффективности. Соответственно, многие из стандартных библиотечных классов Java final, например, java.lang.Systemи java.lang.String. Все методы в finalклассе неявно final.

  • finalМетод не может быть переопределен подклассами. Это используется для предотвращения непредвиденного поведения подкласса, изменяющего метод, который может иметь решающее значение для функции или согласованности класса.

  • finalПеременная может быть инициализирован только один раз, либо с помощью инициализатора или оператора присваивания. Его не нужно инициализировать в точке объявления: это называется blank finalпеременной. Пустая конечная переменная экземпляра класса должна быть обязательно назначена в конце каждого конструктора класса, в котором она объявлена; аналогично, пустая конечная статическая переменная должна быть обязательно назначена в статическом инициализаторе класса, в котором она объявлена; в противном случае ошибка времени компиляции возникает в обоих случаях.

Примечание. Если переменная является ссылкой, это означает, что переменная не может быть связана повторно для ссылки на другой объект. Но объект, на который он ссылается, остается изменчивым, если он изначально был изменчивым.

Когда в теле метода определен анонимный внутренний класс, все переменные, объявленные finalв области действия этого метода, доступны из внутреннего класса. Как только оно было назначено, значение последней переменной не может измениться.

Ashish
источник
5
(Я не опровергал вас) Некоторые дополнительные пояснения: «Статический метод может получить доступ только к статическим данным. Он не может получить доступ к нестатическим данным (переменным экземпляра)» - ЕСЛИ У него есть / создается экземпляр класса. «Статический метод может вызывать только другие статические методы и не может вызывать нестатический метод из него». - ЕСЛИ он не имеет / создает экземпляр класса.
xagyg
1
в статическом методе объяснения синтаксиса вы упомянули неправильно я думаю. это может бытьClass.methodName()
Mdhar9e
у нас тоже может быть статический класс. Внесите исправление в свой ответ. Спасибо :)
Madhusudan
Начиная с Java 8 анонимный класс (и лямбда) может эффективно обращаться к конечным переменным и не ограничивать конечное ключевое слово.
akhil_mittal
38

static означает, что он принадлежит классу, а не экземпляру, это означает, что существует только одна копия этой переменной / метода, совместно используемая всеми экземплярами определенного класса .

public class MyClass {
    public static int myVariable = 0; 
}

//Now in some other code creating two instances of MyClass
//and altering the variable will affect all instances

MyClass instance1 = new MyClass();
MyClass instance2 = new MyClass();

MyClass.myVariable = 5;  //This change is reflected in both instances

final совершенно не связан, это способ определения единожды только инициализации. Вы можете инициализировать при определении переменной или внутри конструктора, нигде больше.

note Примечание к заключительным методам и конечным классам. Это способ явно заявить, что метод или класс нельзя переопределить / расширить соответственно.

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

public class MyClass {

    public static List<String> cars = new ArrayList<String>();

    static {
        cars.add("Ferrari");
        cars.add("Scoda");
    }

}

public class TestClass {

    public static void main(String args[]) {
        System.out.println(MyClass.cars.get(0));  //This will print Ferrari
    }
}

Вы не должны путать это с блоками инициализатора экземпляра, которые вызываются перед конструктором для каждого экземпляра.

Джон Тейлор
источник
Следующий ввод, предоставленный вами, может устранить все недоразумения благодаря ...final is entirely unrelated, it is a way of defining a once only initialization. You can either initialize when defining the variable or within the constructor, nowhere else.
prashant thakre
2
Просто и понятно, как должно быть. Принятый ответ просто .... многословен.
22

Два действительно не похожи. staticПоля - это поля, которые не принадлежат какому-либо конкретному экземпляру класса .

class C {
    public static int n = 42;
}

Здесь staticполе nсвязано не с каким-либо конкретным экземпляром, Cа со всем классом в целом (поэтому C.nего можно использовать для доступа к нему). Вы все еще можете использовать экземпляр Cдля доступа n? Да, но это не считается особенно хорошей практикой.

final с другой стороны, указывает, что конкретная переменная не может измениться после ее инициализации.

class C {
    public final int n = 42;
}

Здесь nнельзя переназначить, потому что это так final. Еще одно отличие состоит в том, что любая переменная может быть объявлена final, в то время как не каждая переменная может быть объявлена ​​статической.

Кроме того, классы могут быть объявлены, finalчто указывает на то, что они не могут быть расширены:

final class C {}

class B extends C {}  // error!

Точно так же методы могут быть объявлены как final, чтобы указать, что они не могут быть переопределены расширяющим классом:

class C {
    public final void foo() {}
}

class B extends C {
    public void foo() {}  // error!
}
arshajii
источник
Спасибо за вклад. Код выдает ошибку: класс C {public static int n = 42; } он говорит, что поле не может объявить static в нестатическом типе. Почему я не могу объявить или сделать Cn?
ТехноКорнер
@TechnoCorner только классы высшего уровня (потенциально publicкласс, который определяет файл) или staticвнутренние классы могут определять staticпеременные. Другие внутренние классы являются экземплярами внешнего класса и не могут иметь статических переменных.
Запл
17

финал -

1) Когда мы применяем ключевое слово « final » к переменной , значение этой переменной остается постоянным. (или) Как только мы объявим переменную как final, значение этой переменной не может быть изменено.

2) Это полезно, когда значение переменной не изменяется в течение срока службы программы.

статический -

1) когда мы применяем ключевое слово « static » к переменной , это означает, что оно принадлежит классу.
2) Когда мы применяем ключевое слово « static » к методу , это означает, что метод может быть доступен без создания какого-либо экземпляра класса

Рохит
источник
12

static означает, что в памяти есть только одна копия переменной, используемая всеми экземплярами класса.

finalКлючевое слово просто означает , что значение не может быть изменено. Без final, любой объект может изменить значение переменной.

Эммануэль Осимосу
источник
3

Статические и финальные имеют некоторые большие различия:

Статические переменные или классы всегда будут доступны из любого места. Final - это просто ключевое слово, означающее, что переменная не может быть изменена. Так что если бы:

public class Test{    
   public final int first = 10;
   public static int second = 20;

   public Test(){
     second = second + 1
     first = first + 1;
   }
}

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

Алистар
источник
3

Думайте об объекте как о спикере Если Speaker - это класс, он будет иметь разные переменные, такие как громкость, высокие частоты, низкие частоты, цвет и т. Д. Вы определяете все эти поля при определении класса Speaker. Например, вы объявили поле цвета со статическим модификатором, это означает, что вы сообщаете компилятору, что существует ровно одна копия этой переменной, независимо от того, сколько раз был создан экземпляр класса.

декларирование

static final String color = "Black"; 

удостоверится, что всякий раз, когда создается экземпляр этого класса, значение цветового поля будет «черным», если оно не изменено.

public class Speaker {

static String color = "Black";

}

public class Sample {

public static void main(String args[]) {
    System.out.println(Speaker.color); //will provide output as "Black"
            Speaker.color = "white";
    System.out.println(Speaker.color);  //will provide output as "White"
}}

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

public class Speaker {

static final String color = "Black";

}

public class Sample {

public static void main(String args[]) {
    System.out.println(Speaker.color); //should provide output as "Black"
            Speaker.color = "white"; //Error because the value of color is fixed.  
    System.out.println(Speaker.color); //Code won't execute.
}}

Вы можете скопировать / вставить этот код прямо в ваш эмулятор и попробовать.

vishnulphb
источник
2

Легкая разница,

Окончательный : означает, что значение переменной является конечным, и оно никуда не изменится Если вы говорите, что final x = 5, это означает, что x нельзя изменить, его значение является окончательным для всех.

статический: означает, что у него есть только один объект. предположим, у вас есть x = 5, в памяти есть x = 5 и его присутствие внутри класса. если вы создаете объект или экземпляр класса, что означает наличие определенного поля, представляющего этот класс и его переменные и методы. и если вы создаете другой объект или экземпляр этого класса, это означает, что в памяти есть два блока того же класса, которые имеют разные x внутри них. и если вы вызовете оба x в разных позициях и измените их значение, то их значение будет другим. В блоке 1 есть x, у которого есть x = 5, а в блоке 2 есть x = 6. Но если вы сделаете x статическим, это означает, что его нельзя создать снова. Вы можете создать объект класса, но этот объект не будет иметь различного х в них. если x является статическим, то и блок 1, и блок 2 будут иметь одинаковый x, значение которого равно 5. Да, я могу изменить значение статического в любом месте, так как это не является окончательным. поэтому, если я скажу, что у box 1 есть x, и я изменяю его значение на x = 5, и после этого я делаю еще один box, который является box2, и я меняю значение box2 x на x = 6. тогда, поскольку X является статическим, оба поля имеют одинаковый x. и оба блока будут давать значение box как 6, потому что box2 перезаписывает значение от 5 до 6.

И финал, и статика совершенно разные. Финал, который является финалом, не может быть изменен. статический, который останется как единое целое, но может быть изменен.

«Это пример. Помните, что статические переменные всегда вызываются по имени класса. Потому что они являются едиными для всех объектов этого класса. Поэтому класс A имеет x = 5, я могу вызвать и изменить его с помощью Ax = 6; "

Малик Усман
источник
1

Статика - это то, что может вызывать любой объект в классе, который по своей природе принадлежит типу объекта.

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

Пример кода:

class someClass
{
   public static int count=0;
   public final String mName;

   someClass(String name)
   {
     mname=name;
     count=count+1;
   }

  public static void main(String args[])
  {
    someClass obj1=new someClass("obj1");
    System.out.println("count="+count+" name="+obj1.mName);
    someClass obj2=new someClass("obj2");
    System.out.println("count="+count+" name="+obj2.mName);
  }
}

Википедия содержит полный список ключевых слов Java .

PearsonArtPhoto
источник
Что вы имеете в виду для конкретного объекта? Не могли бы вы проиллюстрировать.
TechnoCorner
0

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

staticпредназначен для членов класса (атрибутов и методов), и его следует понимать в отличие от экземпляров (не статических) членов. Я бы рекомендовал прочитать «Понимание экземпляров и членов класса» в Учебниках по Java. Я также могу быть использован в staticблоках, но я бы не стал беспокоиться об этом для начала.

finalимеет различные значения в зависимости от того, применяется ли он к переменным, методам, классам или некоторым другим случаям. Здесь мне больше нравятся объяснения из Википедии .

madth3
источник
-1

Значения статических переменных могут быть изменены, хотя одна копия переменной проходит через приложение, тогда как значения Final Variable могут быть инициализированы один раз и не могут быть изменены во всем приложении.

Пол Дебаш
источник