==
сравнивает ссылки на объекты.
.equals()
сравнивает значения String.
Иногда ==
дает иллюзии сравнения значений String, как в следующих случаях:
String a="Test";
String b="Test";
if(a==b) ===> true
Это связано с тем, что при создании любого строкового литерала JVM сначала ищет этот литерал в пуле строк, и если он найдет совпадение, эта же ссылка будет передана новой String. Из-за этого получаем:
(a == b) ===> true
String Pool
b -----------------> "test" <-----------------a
Однако ==
не выполняется в следующем случае:
String a="test";
String b=new String("test");
if (a==b) ===> false
В этом случае для new String("test")
оператор new String будет создан в куче, и эта ссылка будет указана на b
, поэтому b
будет дана ссылка на кучу, а не на String pool.
Теперь a
указывает на String в пуле String, а b
указывает на String в куче. Из-за этого мы получаем:
, если (a == b) ===> false.
String Pool
"test" <-------------------- a
Heap
"test" <-------------------- b
Пока .equals()
всегда сравнивает значение String, поэтому дает true в обоих случаях:
String a="Test";
String b="Test";
if(a.equals(b)) ===> true
String a="test";
String b=new String("test");
if(a.equals(b)) ===> true
Таким образом, использование .equals()
всегда лучше.
Прежде всего, существуют два типа блоков инициализации :
Этот код должен проиллюстрировать их использование и в каком порядке они выполняются:
public class Test {
static int staticVariable;
int nonStaticVariable;
// Static initialization block:
// Runs once (when the class is initialized)
static {
System.out.println("Static initalization.");
staticVariable = 5;
}
// Instance initialization block:
// Runs each time you instantiate an object
{
System.out.println("Instance initialization.");
nonStaticVariable = 7;
}
public Test() {
System.out.println("Constructor.");
}
public static void main(String[] args) {
new Test();
new Test();
}
}
Отпечатки:
Static initalization.
Instance initialization.
Constructor.
Instance initialization.
Constructor.
Блоки инициализации экземпляра полезны, если вы хотите, чтобы какой-то код запускался независимо от того, какой конструктор используется, или если вы хотите выполнить некоторую инициализацию экземпляра для анонимных классов.
public class StaticInitializationBlock {
static int staticVariable;
int instanceVariable;
// Static Initialization Block
static {
System.out.println("Static block");
staticVariable = 5;
}
// Instance Initialization Block
{
instanceVariable = 7;
System.out.println("Instance Block");
System.out.println(staticVariable);
System.out.println(instanceVariable);
staticVariable = 10;
}
public StaticInitializationBlock() {
System.out.println("Constructor");
}
public static void main(String[] args) {
new StaticInitializationBlock();
new StaticInitializationBlock();
}
}
Выход:
Static block
Instance Block
5
7
Constructor
Instance Block
10
7
Constructor
Блок инициализатора определен внутри класса, а не как часть метода. Он выполняется для каждого объекта, созданного для класса. В следующем примере класс Employee
определяет блок инициализатора:
class Employee {
{
System.out.println("Employee:initializer");
}
}
хотел бы добавить к ответу @ aioobe
Порядок выполнения:
Несколько дополнительных моментов, которые следует учитывать (пункт 1 - повторение ответа @ aioobe):
Вопрос не совсем ясен, но вот краткое описание способов инициализации данных в объекте. Предположим, что у вас есть класс A, который содержит список объектов.
1) Поместите начальные значения в объявление поля:
class A {
private List<Object> data = new ArrayList<Object>();
}
2) Назначьте начальные значения в конструкторе:
class A {
private List<Object> data;
public A() {
data = new ArrayList<Object>();
}
}
В обоих случаях предполагается, что вы не хотите передавать «данные» в качестве аргумента конструктора.
Все становится немного сложнее, если вы смешиваете перегруженные конструкторы с внутренними данными, такими как выше , Рассмотрим:
class B {
private List<Object> data;
private String name;
private String userFriendlyName;
public B() {
data = new ArrayList<Object>();
name = "Default name";
userFriendlyName = "Default user friendly name";
}
public B(String name) {
data = new ArrayList<Object>();
this.name = name;
userFriendlyName = name;
}
public B(String name, String userFriendlyName) {
data = new ArrayList<Object>();
this.name = name;
this.userFriendlyName = userFriendlyName;
}
}
Обратите внимание, что существует много повторяющегося кода. Вы можете исправить это, заставив конструкторы вызвать друг друга, или вы можете получить частный метод инициализации, который вызывает каждый конструктор:
class B {
private List<Object> data;
private String name;
private String userFriendlyName;
public B() {
this("Default name", "Default user friendly name");
}
public B(String name) {
this(name, name);
}
public B(String name, String userFriendlyName) {
data = new ArrayList<Object>();
this.name = name;
this.userFriendlyName = userFriendlyName;
}
}
или
class B {
private List<Object> data;
private String name;
private String userFriendlyName;
public B() {
init("Default name", "Default user friendly name");
}
public B(String name) {
init(name, name);
}
public B(String name, String userFriendlyName) {
init(name, userFriendlyName);
}
private void init(String _name, String _userFriendlyName) {
data = new ArrayList<Object>();
this.name = name;
this.userFriendlyName = userFriendlyName;
}
}
Эти два (более или меньше).
Надеюсь, это даст вам несколько советов о том, как инициализировать данные в ваших объектах. Я не буду говорить о статических инициализационных блоках, поскольку это, вероятно, немного продвинуто на данный момент.
EDIT: Я интерпретировал ваш вопрос как «как инициализировать мои переменные экземпляра», а не «как инициализатор блокирует работу ", поскольку блоки инициализации являются относительно продвинутой концепцией, и из тон вопроса кажется, что вы спрашиваете о более простой концепции. Я мог ошибаться.
Чтобы узнать, как использовать статический блок инициализации, обратитесь к исходному коду Class.forName также в этой статье http://cephas.net/blog/2005/07/31/java-classfornamestring-classname- и-jdbc / , они используют блок инициализации для загрузки динамического класса.
хороший ответ by aioobe, добавляющий еще несколько точек
public class StaticTest extends parent {
static {
System.out.println("inside satic block");
}
StaticTest() {
System.out.println("inside constructor of child");
}
{
System.out.println("inside initialization block");
}
public static void main(String[] args) {
new StaticTest();
new StaticTest();
System.out.println("inside main");
}
}
class parent {
static {
System.out.println("inside parent Static block");
}
{
System.out.println("inside parent initialisation block");
}
parent() {
System.out.println("inside parent constructor");
}
}
, это дает
inside parent Static block
inside satic block
inside parent initialisation block
inside parent constructor
inside initialization block
inside constructor of child
inside parent initialisation block
inside parent constructor
inside initialization block
inside constructor of child
inside main
, как это указывает на очевидное, но кажется немного более понятным.
Блоки инициализации выполняются всякий раз, когда класс инициализируется и перед вызовом конструкторов. Они обычно размещаются над конструкторами в фигурных скобках. Не обязательно включать их в свои классы.
Они обычно используются для инициализации ссылочных переменных. Эта страница дает хорошее объяснение
Блок инициализатора содержит код, который всегда выполняется всякий раз, когда создается экземпляр. Он используется для объявления / инициализации общей части различных конструкторов класса.
Порядок конструкторов инициализации и блока инициализации не имеет значения, блок инициализации всегда выполняется перед конструктором.
Что делать, если мы хотим выполнить некоторый код один раз для всех объектов класса?
Мы используем Static Block в Java.
init()
(который кто-то, обновляющий класс, может забыть его вызвать) – pablisco 19 August 2016 в 10:28this
ключевое слово inisde instance initialize block.this
- объект класса curernt, и он будет полностью построен после завершения вызова конструктора? – amarnath harish 18 June 2018 в 09:59