調用構造器是編譯器的責任
㈠ java構造器:什麼是構造器它的作用是什麼
java類中,如果用戶沒有一個類創建構造器,java編譯器就會自動識別,在jvm中為這個類創建一個默認構造器,這個構造器沒有參數。當用戶為類創建一個構造器時,不管這個構造器是否有參數,jvm就不再為該類創建一個無參的構造器了,為了防止這個類被其他類繼承,所以我們要強調,在為類創建構造器時就要創建一個無參的構造器,以防止子類初始化時,調用父類的默認構造器。所以我們創建的這個無參構造器,也是默認構造器。
㈡ C++類的構造函數調用問題
默認構造函數:
聲明類的對象的時候
聲明類的數組的時候(每個元素會單獨調用一次)
調用等號運算符的時候(等號左邊的變數會先調用一次)================================================
最後一句是不對的。上兩句是對的
如果等號左邊的變數還沒有實例化的話,只會調用拷貝構造函數,不會調用默認構造函數的,也不會調用=運算符。 即
CTest aa; //調用默認構造函數
CTest bb = aa; //只會調用拷貝構造函數,不會調用默認構造函數的,也不會調用=運算符。就相當於 CTest bb(aa);
但是如果 aa = bb; //這只會調用=運算符,因為aa已經實例化了
要弄明白拷貝構造函數的意思,就是拷貝一個對象來構造另外一個對象,重點是「構造」這個詞,如果說aa已經被構造了(實例化),那下面還要構造什麼呢,也就不會再調用拷貝構造函數了,能進行的操作只能是重新賦值而已,就是=運算符。但是像CTest bb = aa; 因為bb還沒有構造,那隻能調用拷貝構造函數了
拷貝構造函數:
類的對象作為參數傳遞給函數的時候
類的對象作為返還值的時候
====================================
第一句是對的,第二句是不對的。比如
假如有個函數是這樣(返回類型不管是不是引用類型,下面的結果都是一樣):
CTest getTest() { return m_myTest; }
那麼,
CTest aa; //實例化aa,調用默認構造函數
aa = getTest(); //只會調用 = 運算符,不會調用任何構造函數,因為aa已經實例化了。
CTest bb = getTest(); //此時返回值後只會調用拷貝構造函數,不會調用其他的函數,包括=運算符也不會被調用。
所以不論是賦值還是調用,只要看賦值左邊的變數是否已經被實例化了,如果實例化了,只會調用=運算符, 如果沒有,只會調用拷貝構造函數。類的對象作為參數傳遞給函數的時候(不是引用類型),就是把一個對象給一個沒有實例化的變數賦值,所以這時只會觸發拷貝構造函數,而不是其它函數。
這些都是硬道理,沒什麼再深入講的,如果實在不明白,就死記著吧。
㈢ 關於java構造器的幾點學習筆記
1.構造器: 一個創建對象時被自動調用的特殊方法,為的是初始化。構造器的名稱應與類的名稱一致。
例如:public class Person {
private String name;
private String password;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, String password) {
super();
this.name = name;
this.password = password;
}
}
public static void main(String[] args) {
//初始化
Person person = new Person("張三","123");
}
2.創建一個對象時,系統會該對象的屬性 默認初始化,數值類型屬性的值為0,布爾類型false,引用類型設置為null.
3在子類中調用父類的構造器來初始化父類,那就用合適的參數來調用super(),你用沒有參數的super()來調用父類的構造器(註:同時也沒有使用this()來調用其他構造器),父類預設的構造器會被調用,如果父類沒有預設的構造器,那編譯器就會報一個錯誤。
4. this
4.1構造器中調用this只能放在第一位;
4.2構造器中調用this只能調用一次;
4.3普通方法中不能使用this()調用構造器;
5. 構造器的作用
5.1:創建對象,凡是必須和 new 一起使用
5.2:完成對象的初始化操作
6.注意事項
6.1:構造器的名稱和當前所在類的名稱相同
6.2:禁止定義返回類型,千萬不要使用 void 作為返回類型(這屬於普通方法)
6.3:在構造器中,不需要使用 return 語句(其實構造器是有返回值的,返回的是當前創建對象的引用)
㈣ JAVA構造函數的名字為什麼跟類名一樣
調用構造器是編譯器的責任,所以就需要讓編譯器知道應該調用哪一個方法。把構造函數的名稱設置成和類名一樣的話,那編譯器在載入類的時候就知道了構造函數的方法,因初始化期間(在java中,「初始化」和「創建對象」是捆綁在一起的額,不能分離開來)要自動調用構造器,所以這種做法就比較好了。如果不一樣的情況下,你還得告訴編譯器構造函數的名稱是什麼
㈤ JAVA 構造器
您好樓主。構造器在java中是必須有的。你說「我看見很多代碼中好像沒有啊」。是啊,確實是這樣,但是如果你不顯示的寫出構造器,系統會提供一個默認的無參數的構造器。
構造器,顧名思義就是構造某種東西的,這里是構造對象的。樓主應該看到調用方法是怎麼用的吧,就是實例名加上「.」方法名,例如a.getSize()。其實你創造對象,比如Test test=new Test();這個new關鍵字,其實就是調用的Test這個對象,然後賦值給「test」。
構造器另一個用途是初始化代碼的。您說「不就是賦個初值嗎?就直接賦值不就行了?難道初始化不是賦初值嗎?」這個我認為,應該是一種編程習慣吧。將需要賦值的變數在構造器中初始化,這樣可能防止忘記賦初值吧。可能是這樣!我看到的很多例子中,大部分都是在構造器中進行初始化的,除了靜態的,或者最終的變數。
樓上的建議不錯,看看《thinking in java》,這里是深入的,我也正在研究。
㈥ c# 構造函數的調用
下面是我學過C#的一點理解,希望對你有幫助!
很簡單的,構造函數實際就是在主類和其他類之間傳遞參數用的,看看這兩段代碼,
關於自動調用,構造函數的自動調用是根據參數的數量進行區分的,比如下面第一段代碼,CoOrds類中有兩個構造函數,到底調用哪一個,就看主類中對象實例化的時候,類名里寫了幾個參數: p1是CoOrds(),沒有參數,所以自動調用第一個構造函數,同理,p2調用第二個
至於為什麼要new, new的意思不是調用,而是實例化,初始化一個類,這個概念我是這樣理解的, 已經寫好的CoOrds類好比一個工具模具,你要在主類中使用的時候,不可能用模板來操作吧,這時候,你需要用模具來復制一個嶄新的工具供你使用,new就好比是把模具拿來製造新工具的過程。
phblic class CoOrds
{
public CoOrds()
{
x = 0;
y = 0;
}
public CoOrds(int x, int y)
{
this.x = x;
this.y = y;
}
}
……
CoOrds p1 = new CoOrds();
CoOrds p2 = new CoOrds(5, 3);
……
㈦ 關於java構造器的詳細解釋,謝謝。
首先要注意的是Java的構造器並不是函數,所以他並不能被繼承,這在我們extends的時候寫子類的構造器時比較的常見,即使子類構造器參數和父類的完全一樣,我們也要寫super就是因為這個原因。
構造器的修飾符比較的有限,僅僅只有public private protected這三個,其他的例如任何修飾符都不能對其使用,也就是說構造器不允許被成名成抽象、同步、靜態等等訪問限制以外的形式。
因為構造器不是函數,所以它是沒有返回值的,也不允許有返回值。但是這里要說明一下,構造器中允許存在return語句,但是return什麼都不返回,如果你指定了返回值,雖然編譯器不會報出任何錯誤,但是JVM會認為他是一個與構造器同名的函數罷了,這樣就會出現一些莫名其妙的無法找到構造器的錯誤,這里是要加倍注意的。
在我們extends一個子類的時候經常會出現一些意想不到的問題,我在這里說一些和構造器有關的。
首先說一下Java在構造實例時的順序(不討論裝載類的過程)
構造的粗略過程如下
1、分配對象空間,並將對象中成員初始化為0或者空,java不允許用戶操縱一個不定值的對象。
2、執行屬性值的顯式初始化(這里有一點變化,一會解釋,但大體是這樣的)
3、執行構造器
4、將變數關聯到堆中的對象上
介紹一下准備知識,以備一會來詳細說明這個的流程
this() super()是你如果想用傳入當前構造器中的參數或者構造器中的數據調用其他構造器或者控制父類構造器時使用的,在一個構造器中你只能使用this()或者super()之中的一個,而且調用的位置只能在構造器的第一行, 在子類中如果你希望調用父類的構造器來初始化父類的部分,那就用合適的參數來調用super(),如果你用沒有參數的super()來調用父類的構造器(同時也沒有使用this()來調用其他構造器),父類預設的構造器會被調用,如果父類沒有預設的構造器,那編譯器就會報一個錯誤,注意此處,我們經常在繼承父類的時候構造器中並不寫和父類有關的內容,此時如果父類沒有預設構造器,就會出現編譯器添加的預設構造器給你添麻煩的問題了哦。例如:Class b extends a{public b(){}}就沒有任何有關父類構造器的信息,這時父類的預設構造器就會被調用。你必須在構造器的第一行放置super或者this構造器,否則編譯器會自動地放一個空參數的super構造器的,其他的構造器也可以調用super或者this,調用成一個遞歸構造鏈,最後的結果是父類的構造器(可能有多級父類構造器)始終在子類的構造器之前執行,遞歸的調用父類構造器
使用構造器中的注意事項。
一、構造器中一定不要創建自身的實例,否則會造成調用棧溢出錯誤。這個規則也適用於對象的實例變數,如果對象中有自身的引用,這個引用一定不能在定義中或者構造器中初始化。
class a
{
a _a = new a();
public a()
{
_a = new a();
a _b = new a();
}
}
以上三種情況都會造成棧溢出,呵呵,這樣會造成一個無窮遞歸的調用棧。
二、如果父類是一個抽象類,那通過調用父類的構造器,也可以將它初始化,並且初始化其中的數據。
三、如果你要在構造器中調用一個方法時,將該方法聲明為private。
對於這個規則是需要一些說明的,假使你的父類構造器中要調用一個非靜態方法,而這個方法不是private的又被子類所重載,這樣在實際創建子類的過程中遞歸調用到了父類的構造器時,父類構造器對這個方法的調用就會由於多態而實際上調用了子類的方法,當這個子類方法需要用到子類中實例變數的時候,就會由於變數沒有初始化而出現異常(至於為什麼子類中的實例變數沒有初始化可以參考上邊的實例初始化過程),這是Java不想看到的情況。而當父類構造器中調用的方法是一個private方法時,多態就不會出現,也就不會出現父類構造器調用子類方法的情況,這樣可以保證父類始終調用自己的方法,即使這個方法中調用了父類中的實例變數也不會出現變數未初始化的情況(變數初始化總是在當前類構造器主體執行之前進行)。
㈧ JAVA裡面子類調用父類的構造器有什麼意思
因為如果父類有私有成員變數的話,一般在父類的構造器中初始化,因為子類構造器無法訪問·父類的私有成員。也就是說繼承來的父類的部分就應該由父類構造方法來構造,子類構造方法就只構造屬於子類的那部分。所以即時你沒有顯式調用父類的無參構造方法,編譯器也會幫你加上,如果父類沒有無參構造方法,你又沒有顯式調用有參構造方法,就會報錯。