Constructor ها یا سازنده ها در جاوا ویژگی هستند که با استفاده از آنها می توان متغییر های یک کلاس را در هنگام ایجاد نمونه از آن را مقدار دهی کرد یا مقداری را به کلاس دیگر ارسال کرد که این پارامتر ارسالی می تواند آبجکت ایجاد شده از یک کلاس باشد.
هر کلاسی در جاوا می تواند n کانستراکتور داشته باشد.
اگر برای کلاسی کانستراکتور تعیین نشود در هنگام ایجاد نمونه از آن کلاس به صورت خودکار یک کانستراکتور پیش فرض برای آن ایجاد خواهد شد.
نمونه ایی از یک کلاس ساده با یک سازنده پیش فرض (Default Constructor) :

public class Test {
     public Test(){
         System.out.println("print from constructor");
     }
}

در این کلاس چون کانستراکتور Test() فاقد پارامتر است کانستراکتور پیش فرض می باشد.
یک کانستراکتور باید هم نام با نام کلاس باشد.در کلاس Test تمامی سازنده ها باید با نام Test ایجاد شوند.
یک سازنده می تواند سازنده ی دیگر همان کلاس را فراخوانی کند یا در بحث شی گرایی یک سازنده کلاس می تواند سازنده ی کلاسی که از آن مشتق شده یا ارث بری می کند را فراخوانی کند (با اشاره گر های this و super).
سازنده ها نوع بازگشتی ندارند یعنی مقداری را return نمی کنند.
نوع دسترسی کانستراکتور ها می تواند public ، private ، protected و یا default access باشد.
سازنده ها می توانند تعداد پارامتر های یکسان اما با نوع داده ایی متفاوت باشد.به مثال زیر توجه کنید :

public class Test2 {
     public Test2(int i){}
     public Test2(double d){}
     public Test2(String s){}
}

نکته قابل توجه این است که هر سه سازنده دارای یک پارامتر می باشند و هم نام اند ولی دارای پارامتر هایی با نوع داده ایی متفاوت می باشند که آنها را از هم متمایز می کند. این تمایز زمانی مشخص می شود که شما در حال ایجاد آبجکتی از کلاس باشید. برای نمونه :

public class ConstructorTest {
    Test2 t1;
    Test2 t2;
    Test2 t3;
    public static void main(String[] args){
        t1 = new Test2(1);
        t2 = new Test2(10.2);
        t3 = new Test3("String");
    }
}

در اینجا پارامتر هر نمونه ایی که از کلاس Test2 ایجاد کرده ایم در حین عمل new کردن، مشخص می کند که نمونه ی ایجاد شده (در اینجا t1 t2 t3) با کدام یک از کانستراکتور کلاس Test2 نمونه سازی شود. به هر حال با اجرای برنامه عملی اتفاق نمی افتد زیرا دستوری در سازنده ها وجود ندارد.
نکته ی مهم در کلاس Test2 این است که این کلاس سازنده ی پیش فرض ندارد.زمانی که ما برای کلاس سازنده ایی تعریف نکنیم به صورت خودکار برای کلاس سازنده پیش فرض در نظر گرفته می شود تا از بروز خطاهایی که می توانند ناشی از فراموشی برنامه نویس برای ایجاد سازنده پیش فرض باشد جلوگیری شود.
اما زمانی که شما سازندهی پیش فرض تعریف نمی کنید اما کلاس دارای سازنده می باشد مانند مثال زیر :

public class Test3 {
    public Test3(int i){}
    public static void main(String[] args){
        Test3 t1 = new Test3(); // compile error
        Test3 t2 = new Test3(10);
    }
}

دلیل اینکه نمونه t1 یک خطای زمان کامپایل می باشد این است که کلاس سازنده پیش فرض ندارد و چون دارای سازنده ایی با پارامتر می باشد به صورت خوذکار برای آن سازنده پیش فرض در نظر گرفته نمی شود.
پس این نکته مهم را باید توجه داشته باشیم.
خوب حالا مثالی از سازنده برای مقدار دهی متغییر های یک کلاس در زمان ایجاد نمونه از آن کلاس در ادامه مطالب ارائه می دهیم.
کلاسی به نام Student داریم که سه متغییر به نام name و field و age دارد که به ترتیب نام رشته سن دانش آموز را مشخص می کند و کانستراکتور پیش فرض و یک کانستراکتور تعریف شده با سه پارامتر دارد:

 public class Student {
    int age;
    String name, field;
    public Student(){
        name = "unknown";
        field = "unknown";
        age = 0;
    }
    public Student(String _name, String _field, int _age){
        name  = _name;
        field = _field;
        age = _age;
    }
}

حالا کلاسی مانند کلاس زیر برای استفاده از کلاس Student ایجاد می کنیم.

public class UseStudent {
    public static void main(String[] args){
        Student st1 = new Student();
        Student st2 = new Student("delnia", "IT", 23);
        System.out.println("st1 object : " + st1.name + ", " + st1.field + ", "+ st1.age);
        System.out.println("st2 object : " + st2.name + ", " + st2.field + ", "+ st2.age);
    }
}

مطمئنا خروجی برنامه چیزی جز خروجی زیر نمی باشد:

st1 boject : unknown, unknown, 0
st2 boject : delnia, IT, 23

خوب st1 از سازنده پیش فرض استفاده کرد و چون پارامتری نداشت مقدار های unknown را برای اسم و رشته و مقدار 0 را برای سن قرار دارد.اما st2 تمامی مقادیری را که با پارامتر به آن کلاس ارسال کردیم را در متغییر های مربوطه جایگزاری کرد که بعد از چاپ مقادیر مربوط به هر آبجکت صحت امر مشخص شد.
اما چند نکته کلیدی :
1- در کلاس Student سازنده ایی که تعریف کردیم سه پارامتر دارد و اسم پارامتر های موجود را هم نام با نام متغییر های کلاس قرار ندادیم.چرا؟
چون که اگر نام یکسان داشته باشند در زمان انتساب کردن مقدار چیزی به متغییر کلاس انتساب داده نمی شود و مانند این است که مقدار متغییر مجازی در پارامتر را با خودش انتساب دهیم.بنابر این برای اینکه کامپایلر متوجه شود منظور ما از متغییر ها دقیقا کدامیک هستند نام ها را متفاوت انتخاب می کنیم که این مفهوم خود نشان دهنده متغییر های محلی و سراسری می باشد که در کانستراکتور اگر ما متغییری به نام name در پارامتر  قرار دهیم کامپایلر پارامتر name موجود در پارامتر را معتبر می داند و آن را ملاک قرار می دهد.
اما می توان با استفاده از اشاره گر this این مشکل را حل کرد (در پست های قبلی توضیح داده شد)  یک مثال کوتاه :

public class Student {
    int age;
    String name, field;
    public Student(String name, String field, int age){
        this.name  = name;
        this.field = field;
        this.age = age;
    }
}

تنها توضیح کوچک در رابطه با this این است که : this اشاره گر به آبجکت جاری می باشد.
و این یک کاربرد this می باشد که در این پست بیشتر توضیح داده شد.