Если вы не инициализировали ссылочный тип и хотите установить или прочитать одно из его свойств, он будет генерировать исключение NullReferenceException.
Пример:
Person p = null;
p.Name = "Harry"; // NullReferenceException occurs here.
Вы можно просто избежать этого, проверив, является ли переменная не нулевой:
Person p = null;
if (p!=null)
{
p.Name = "Harry"; // Not going to run to this point
}
Чтобы полностью понять, почему выбрано исключение NullReferenceException, важно знать разницу между типами значений и ссылочные типы .
Итак, если вы имеете дело со типами значений, NullReferenceExceptions не может произойти. Хотя вам нужно поддерживать оповещение при работе со ссылочными типами!
Только ссылочные типы, как следует из названия, могут содержать ссылки или буквально буквально ничто (или «нуль»). Если типы значений всегда содержат значение.
Типы ссылок (эти должны быть проверены):
Типы значений (вы можете просто игнорировать эти):
Ключевое слово this можно использовать для вызова конструктора из конструктора при написании нескольких конструкторов для класса, есть моменты, когда вы хотите вызвать один конструктор из другого, чтобы избежать дублирования кода .
Bellow - это ссылка, в которой я рассказываю другую тему о конструкторе и getters () и seters (), и я использовал класс с двумя конструкторами. Я надеюсь, что объяснения и примеры помогут вам.
Используя this(args)
. Предпочтительный шаблон - работать от самого маленького конструктора до самого большого.
public class Cons {
public Cons() {
// A no arguments constructor that sends default values to the largest
this(madeUpArg1Value,madeUpArg2Value,madeUpArg3Value);
}
public Cons(int arg1, int arg2) {
// An example of a partial constructor that uses the passed in arguments
// and sends a hidden default value to the largest
this(arg1,arg2, madeUpArg3Value);
}
// Largest constructor that does the work
public Cons(int arg1, int arg2, int arg3) {
this.arg1 = arg1;
this.arg2 = arg2;
this.arg3 = arg3;
}
}
Вы также можете использовать недавно защищенный подход значенияOf или просто «из»:
public class Cons {
public static Cons newCons(int arg1,...) {
// This function is commonly called valueOf, like Integer.valueOf(..)
// More recently called "of", like EnumSet.of(..)
Cons c = new Cons(...);
c.setArg1(....);
return c;
}
}
Чтобы вызвать суперкласс, используйте super(asdf)
. Вызов супер должен быть первым вызовом в конструкторе или вы получите ошибку компилятора.
newCons
заключается в том, что вы пытаетесь изменить состояние объекта, используя setArg1(...)
, который, скорее всего, должен установить свои поля как final. Поскольку мы стараемся как можно больше сохранить неизменяемый объект, если не полностью, шаблон построителя будет исправлять эту проблему более корректно.
– YoYo
30 January 2016 в 07:46
K(A a, B b) { this.a = a; this.b = b; }
. Тогда, если b
имеет разумное значение по умолчанию, может быть конструктор с одним аргументом K(A a) { this(a, DEFAULT_B); }
, и если есть значение по умолчанию a
, у нас есть конструктор по умолчанию: K() { this(DEFAULT_A); }
. Это довольно распространенное соглашение в Java.
– Joshua Taylor
17 May 2018 в 13:12
Вы можете создать конструктор из другого конструктора того же класса, используя ключевое слово this. Пример -
class This1
{
This1()
{
this("Hello");
System.out.println("Default constructor..");
}
This1(int a)
{
this();
System.out.println("int as arg constructor..");
}
This1(String s)
{
System.out.println("string as arg constructor..");
}
public static void main(String args[])
{
new This1(100);
}
}
Выход - строка как конструктор arg .. Конструктор по умолчанию .. int как конструктор arg ..
Внутри конструктора вы можете использовать ключевое слово this
для вызова другого конструктора в том же классе. Это называется явным вызовом конструктора.
Вот еще один класс Rectangle с другой реализацией от той, что находится в разделе «Объекты».
public class Rectangle {
private int x, y;
private int width, height;
public Rectangle() {
this(1, 1);
}
public Rectangle(int width, int height) {
this( 0,0,width, height);
}
public Rectangle(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
}
Этот класс содержит набор конструкторов. Каждый конструктор инициализирует некоторые или все переменные-члены прямоугольника.
Rectangle(int width, int height)
в Rectangle()
вместо Rectangle(int x, int y, int width, int height)
?
– ANjaNA
18 July 2015 в 02:58
Довольно простой
public class SomeClass{
int number;
String someString;
public SomeClass(){
number = 0;
}
public SomeClass(int number){
this(); //set the class to 0
this.setNumber(number);
}
public SomeClass(int number, String someString){
this(number); //call public SomeClass( int number )
}
public void setNumber(int number){
this.number = number;
}
public void setString(String someString){
this.someString = someString;
}
//.... add some accessors
}
теперь вот небольшой небольшой кредит:
public SomeOtherClass extends SomeClass {
public SomeOtherClass(int number, String someString){
super(number, someString); //calls public SomeClass(int number, String someString)
}
//.... Some other code.
}
Надеюсь, что это поможет.
Да, можно вызвать один конструктор из другого с помощью this()
class Example{
private int a = 1;
Example(){
this(5); //here another constructor called based on constructor argument
System.out.println("number a is "+a);
}
Example(int b){
System.out.println("number b is "+b);
}
Вызов конструктора из другого конструктора
class MyConstructorDemo extends ConstructorDemo
{
MyConstructorDemo()
{
this("calling another constructor");
}
MyConstructorDemo(String arg)
{
System.out.print("This is passed String by another constructor :"+arg);
}
}
Также вы можете вызвать родительский конструктор с помощью super()
вызова
Вы можете вызвать другой конструктор с помощью ключевого слова this(...)
(когда вам нужно вызвать конструктор из того же класса) или ключевое слово super(...)
(когда вы нужно вызвать конструктор из суперкласса).
Однако такой вызов должен быть первым утверждением вашего конструктора. Чтобы преодолеть это ограничение, используйте этот ответ .
Когда мне нужно вызвать другой конструктор изнутри кода (не в первой строке), я обычно использую вспомогательный метод, подобный этому:
class MyClass {
int field;
MyClass() {
init(0);
}
MyClass(int value) {
if (value<0) {
init(0);
}
else {
init(value);
}
}
void init(int x) {
field = x;
}
}
Но чаще всего я пытаюсь сделать это другими способами, вызывая, насколько это возможно, более сложные конструкторы из простых в первой строке. Для приведенного выше примера
class MyClass {
int field;
MyClass(int value) {
if (value<0)
field = 0;
else
field = value;
}
MyClass() {
this(0);
}
}
Как уже говорили все, вы используете this(…)
, который называется вызовом явного конструктора .
Однако имейте в виду, что в таком явном выражении вызова конструктора вы можете не ссылаться на
this
или super
. Как указано в JLS (§8.8.7.1).
Он называется привязкой к троекрату или цепочке конструкторов Teleescoping Constructor. Да, вы можете это сделать. Я вижу много примеров выше, и я хочу добавить, сказав, что если вы знаете, что вам нужен только два или три конструктора, возможно, все в порядке. Но если вам нужно больше, попробуйте использовать другой шаблон дизайна, такой как шаблон Builder. Например:
public Omar(){};
public Omar(a){};
public Omar(a,b){};
public Omar(a,b,c){};
public Omar(a,b,c,d){};
...
Вам может потребоваться больше. В этом случае лучшим вариантом будет шаблон Builder. Вот статья, может быть полезно https://medium.com/@modestofiguereo/design-patterns-2-the-builder-pattern-and-the-telescoping-constructor-anti-pattern-60a33de7522e
Я знаю, что есть так много примеров этого вопроса, но то, что я нашел, я помещаю здесь, чтобы поделиться своей идеей. существует два способа построения конструктора. В том же классе вы можете использовать это ключевое слово. в Inheritance вам нужно использовать ключевое слово super.
import java.util.*;
import java.lang.*;
class Test
{
public static void main(String args[])
{
Dog d = new Dog(); // Both Calling Same Constructor of Parent Class i.e. 0 args Constructor.
Dog cs = new Dog("Bite"); // Both Calling Same Constructor of Parent Class i.e. 0 args Constructor.
// You need to Explicitly tell the java compiler to use Argument constructor so you need to use "super" key word
System.out.println("------------------------------");
Cat c = new Cat();
Cat caty = new Cat("10");
System.out.println("------------------------------");
// Self s = new Self();
Self ss = new Self("self");
}
}
class Animal
{
String i;
public Animal()
{
i = "10";
System.out.println("Animal Constructor :" +i);
}
public Animal(String h)
{
i = "20";
System.out.println("Animal Constructor Habit :"+ i);
}
}
class Dog extends Animal
{
public Dog()
{
System.out.println("Dog Constructor");
}
public Dog(String h)
{
System.out.println("Dog Constructor with habit");
}
}
class Cat extends Animal
{
public Cat()
{
System.out.println("Cat Constructor");
}
public Cat(String i)
{
super(i); // Calling Super Class Paremetrize Constructor.
System.out.println("Cat Constructor with habit");
}
}
class Self
{
public Self()
{
System.out.println("Self Constructor");
}
public Self(String h)
{
this(); // Explicitly calling 0 args constructor.
System.out.println("Slef Constructor with value");
}
}
Я расскажу вам простой способ
Существует два типа конструкторов:
Я объясню в одном примере
class ConstructorDemo
{
ConstructorDemo()//Default Constructor
{
System.out.println("D.constructor ");
}
ConstructorDemo(int k)//Parameterized constructor
{
this();//-------------(1)
System.out.println("P.Constructor ="+k);
}
public static void main(String[] args)
{
//this(); error because "must be first statement in constructor
new ConstructorDemo();//-------(2)
ConstructorDemo g=new ConstructorDemo(3);---(3)
}
}
В приведенном выше примере я показал 3 типа вызова
Примечание: это должно быть первое утверждение в конструкторе.
Существуют шаблоны проектирования, которые покрывают потребность в сложной конструкции - если это невозможно сделать лаконично, создайте фабричный метод или фабричный класс.
С последней версией java и добавлением lambdas, легко создать конструктор, который может принять любой желаемый код инициализации.
class LambdaInitedClass {
public LamdaInitedClass(Consumer<LambdaInitedClass> init) {
init.accept(this);
}
}
Вызовите его с помощью ...
new LambdaInitedClass(l -> { // init l any way you want });
Да, можно вызвать один конструктор из другого. Но есть правило. Если вызов выполняется из одного конструктора в другой, то
, что новый вызов конструктора должен быть первым утверждением в текущем конструкторе
blockquote>public class Product { private int productId; private String productName; private double productPrice; private String category; public Product(int id, String name) { this(id,name,1.0); } public Product(int id, String name, double price) { this(id,name,price,"DEFAULT"); } public Product(int id,String name,double price, String category){ this.productId=id; this.productName=name; this.productPrice=price; this.category=category; } }
Итак, что-то вроде ниже не будет работать.
public Product(int id, String name, double price) { System.out.println("Calling constructor with price"); this(id,name,price,"DEFAULT"); }
Также, в случае наследования, когда объект подкласса создается, сначала вызывается конструктор суперкласса.
public class SuperClass { public SuperClass() { System.out.println("Inside super class constructor"); } } public class SubClass extends SuperClass { public SubClass () { //Even if we do not add, Java adds the call to super class's constructor like // super(); System.out.println("Inside sub class constructor"); } }
Таким образом, в этом случае другой вызов конструктора сначала объявляется перед любыми другими операторами.
Да, любое число конструкторов может присутствовать в классе, и их можно вызвать другим конструктором с помощью this()
[Пожалуйста, не путайте конструкторский вызов this()
с ключевым словом this
]. this()
или this(args)
должны быть первой строкой в конструкторе.
Пример:
Class Test {
Test() {
this(10); // calls the constructor with integer args, Test(int a)
}
Test(int a) {
this(10.5); // call the constructor with double arg, Test(double a)
}
Test(double a) {
System.out.println("I am a double arg constructor");
}
}
Это называется перегрузкой конструктора. Обратите внимание, что для конструктора применима только концепция перегрузки, а не наследование или переопределение.
[ Примечание. Я просто хочу добавить один аспект, который я не видел в других ответах: как преодолеть ограничения требования о том, что это () должно быть в первой строке). ]
В Java другой конструктор того же класса можно вызвать из конструктора через this()
. Обратите внимание, что this
должен находиться в первой строке.
public class MyClass {
public MyClass(double argument1, double argument2) {
this(argument1, argument2, 0.0);
}
public MyClass(double argument1, double argument2, double argument3) {
this.argument1 = argument1;
this.argument2 = argument2;
this.argument3 = argument3;
}
}
То, что this
должно появиться в первой строке, выглядит большим ограничением, но вы можете построить аргументы других конструкторов через статические методы. Например:
public class MyClass {
public MyClass(double argument1, double argument2) {
this(argument1, argument2, getDefaultArg3(argument1, argument2));
}
public MyClass(double argument1, double argument2, double argument3) {
this.argument1 = argument1;
this.argument2 = argument2;
this.argument3 = argument3;
}
private static double getDefaultArg3(double argument1, double argument2) {
double argument3 = 0;
// Calculate argument3 here if you like.
return argument3;
}
}
this(...)
), тогда было бы разумно предположить, что где-то была сделана ужасная ошибка, и что дизайн, возможно, нуждается в переосмыслении.
– Engineer Dollery
8 June 2016 в 23:00
final
(окончательные поля могут быть инициализированы только один раз).
– Christian Fries
13 June 2018 в 06:06