導航:首頁 > 源碼編譯 > 編譯時的數據對象

編譯時的數據對象

發布時間:2022-01-21 04:37:47

java創建對象是在編譯時還是在運行時

運行期。編譯好的java程序(即.class文件)需要運行在JVM中。程序,無論代碼還是數據,都需要存儲在內存中。JVM為java程序提供並管理所需要的內存空間。JVM內存分為"堆"、"棧"、"方法區"三個區域,分別用於存儲不同數據。首先JVM會檢查創建這個對象的類是否是一個以前從沒有見過的類型,如果不是,JVM將為其分配內存,如果是,java虛擬機將調用具體的ClassLoader找到對應的.class文件,並將這個文件的內容讀到內存中去。
1)堆:
1.1)用於存儲所有new出來的對象(包括成員變數)。
1.2)垃圾:沒有任何引用所指向的對象。
垃圾回收器(GC)不定時到內存中清掃垃圾,
並不一定一發現垃圾就立刻回收,
回收過程是透明的(看不到的),
通過調用System.gc()可以建議虛擬機盡快調度GC來回收。
1.3)內存泄漏:不再使用的內存沒有被及時的回收。
建議:不再使用的對象,及時將引用設置為null。
1.4)成員變數的生命周期:
創建對象時存儲在堆中,對象被回收時一並被回收。
2)棧:
2.1)用於存儲正在調用的方法中的所有局部變數(包括參數)
2.2)JVM會為每一個正在調用的方法分配一塊對應的棧幀,
棧幀中存儲方法中的局部變數(包括參數),
方法調用結束時,棧幀被清除,局部變數一並被清除。
2.3)局部變數的生命周期:
調用方法時存在棧中,方法結束時與棧幀一並被清除。
3)方法區:
3.1)用於存儲.class位元組碼文件(包括方法)。
3.2)方法只有一份,通過this來區分具體的對象。
既然對象在堆中創建,因此Java創建對象是在運行時,而不是編譯時。

⑵ 編譯時和運行時對象分別是什麼數據類型

運行時類型是程序運行過程中再判斷是什麼類型,編譯時類型是在寫好代碼後,編譯時已經確定是什麼類型了

⑶ 用命令導入資料庫時出現創建的對象帶有編譯警告,終止導入

編譯警告一般是指存儲過程,視圖什麼的腳本出現問題,不知道你的導入時基於用戶的還是全庫的,你需要查看出問題的OBJECT,看看是報的什麼錯,有可能是基於DB_LINK的錯誤,也有可能是調用了其他用戶的表或視圖,而你這一次導入的時候遺漏了

⑷ 儲存在資料庫中的編譯對象有哪些

表: 由行和列構成的集合,用來存儲數據
數據類型: 定義列或變數的數據類型,SQL Server提供了系統數據類型,並允許用戶自定義數據類型
視圖 :由表或其他視圖導出的虛擬表
索引 :為數據快速檢索提供支持且可以保證數據唯一性的輔助數據結構
約束 :用於為表中的列定義完整性的規則
默認值: 為列提供的預設值
存儲過程: 存放於伺服器的預先編譯好的一組T-SQL語句
觸發器: 特殊的存儲過程,當用戶表中數據改變時,該存儲過程被自動執行

⑸ java中的全局變數和靜態變數是在編譯時分配內存還是在載入時分配內存

全局變數是在創建對象的時候分配內存的 創建對象過程為

  1. 分配空間。

  2. 遞歸的創建父類對象。

  3. 初始化成員變數。

  4. 調用構造方法創建一個對象。

靜態變數是在類載入的時候分配空間的,靜態變數和對象沒有關系 是在JVM第一次讀到一個類的時候載入信息的過程中分配空間的 載入過程為

1 .載入父類(如果父類已經載入過,則不在載入)。

2.初始化靜態屬性 。

3 .按順序的初始化靜態代碼塊 初始化的前提就是分配空間 。

而且靜態變數在以後的創建對象的時候不在初始化 所以一般用靜態來保存共享信息

⑹ C++中,只有類,沒有對象,編譯時是否會賦予類被分配空間的能力

你說的「空間」看來是指數據呢。那確實是不會。
另外對於函數,沒有被調用到,運行時就不會給它分配對應空間,這指的也是數據空間

代碼空間的話,類或者函數,都有。

⑺ String s=new String("xyz");編譯時創建兩個對象

2個對象 堆區中1個,常量池中1一個

String a="xyz";首先會到常量池中去查找,如果存在就不再分配,如果不存在就分配,常量池中的數據是在編譯期賦值的,也就是生成class文件時就把它放到常量池裡了

⑻ "對象的屬性名在編譯時才能知道" 怎麼理解

個人 猜測 不一定準確.
比如 你 要載入一個插件,或者 調用一個第三方的對象,它按照某個標准編譯,但是能提供什麼 你開始時不知道,但是 它提供了一個查詢的方法,你可以查詢.

⑼ 如何將一個類中的數據成員聲明為另一個類的對象

class),也稱為嵌入類(nested class),它是定義在其他類的內部。內部類作為其外部類的一個成員,與其他成員一樣,可以直接訪問其外部類的數據和方法。只不過相比較外部類只有public和默認的修飾符不同,內部類作為一個成員,可以被任意修飾符修飾。編譯器在編譯時,內部類的名稱為OuterClass$InnerClass.class 。

1、內部類訪問數據變數
當在某些時候,內部類中定義的變數與外部類中變數名稱相同時,如何確保正確地訪問每一個變數呢?

1.1在main中直接從外部類調用內部類的方法

class Outer
{
private int index = 10;
class Inner
{
private int index = 20;
void print()
{
int index = 30;
System.out.println(this); // the object created from the Inner
System.out.println(Outer.this); // the object created from the Outer
System.out.println(index); // output is 30
System.out.println(this.index); // output is 20
System.out.println(Outer.this.index); // output is 10
}
}

void print()
{
Inner inner = new Inner();//得到內部類的引用
inner.print();
}
}

class Test
{
public static void main(String[] args)
{
Outer outer = new Outer();
outer.print();
}
}
在這里內部類Inner中關鍵字this指向內部類Inner的對象,如果要想指向外部類的對象,必須在this指針前加上外部類名稱,表示this是指向外部類構造的碎屑,如Outer.this 。

1.2在main中顯式返回內部類引用

class Outer
{
private int index = 10;
class Inner
{
private int index = 20;
void print()
{
int index = 30;
System.out.println(index);
System.out.println(this.index);
System.out.println(Outer.this.index);
}
}

Inner getInner()
{
return new Inner();//返回一個內部類的引用
}
}

class Test
{
public static void main(String[] args)
{
Outer outer = new Outer();
Outer.Inner inner = outer.getInner();
inner.print();
}
}
Inner是Outer的內部類,所以在類Test中必須用屬性引用符來標識出內部類。

1.3當main方法在Outer類內部

class Outer
{
private int index = 10;
class Inner
{
private int index = 20;
void print()
{
int index = 30;
System.out.println(index);
System.out.println(this.index);
System.out.println(Outer.this.index);
}
}

Inner getInner()
{
return new Inner();//返回一個內部類的引用
}

public static void main(String[] args)
{
Outer outer = new Outer();
Inner inner = outer.getInner(); // 注意此處變化
inner.print();
}
}
因為main方法在Outer內部,故可以直接引用,不需要屬性引用符。

1.4在main方法中直接產生內部類對象

class Test
{
public static void main(String[] args)
{
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner(); // 注意此處變化
inner.print();
}
}
在利用new構造方法構造一個外部類對象時,並沒有連帶著構造一個內部類對象,故需要訪問內部類方法時,必須使用new操作符為這個外部類對象再構造一個內部類對象。

2、局部內部類
在方法中定義的內部類是局部內部類,它只能訪問方法中的final類型的局部變數,因為用final定義的局部變數相當於是一個常量,延長了其生命周期,使得方法在消亡時,其內部類仍可以訪問該變數。另外,它同樣也可以引用定義在外部類的變數和方法。而且方法體中的局部內部類不允許有訪問修飾符。

class Outer
{
int num=10;
public void print(final int aArgs)
{
class Inner
{
int num=20;
public Inner()
{
System.out.println("This is Inner.");//此句可看出它與匿名內部類用法的不同。
}

public void print()
{
int num=30;
System.out.println(this); // the object created from the local Inner
System.out.println(num);
System.out.println(this.num);
System.out.println(Outer.this.num);
System.out.println(aArgs);
}
}
Inner inner=new Inner();//此句必須放在定義類Inner的後面
inner.print();
}

public static void main(String[] args)
{
Outer outer=new Outer();
outer.print(40);
}
}
對於局部類的命名,不管是在一個方法中定義多個類還是在幾個方法中分別定義類,其編譯後命名是:OuterClass$1InnerClass.class

3、匿名內部類
匿名內部類作為一種特殊的內部類,除了具有普通內部類的特點,還有自己的一些獨有特性:
匿名內部類必須擴展一個基類或實現一個介面,但是不能有顯式的extends和implements子句;
匿名內部類必須實現父類以及介面中的所有抽象方法;
匿名內部類總是使用父類的無參構造方法來創建實例。如果是實現了一個介面,則其構造方法是Object();
匿名內部類編譯後的命名為:OuterClass$n.class,其中n是一個從1開始的整數,如果在一個類中定義了多個匿名內部類,則按照他們的出現順序從1開始排號。

abstract class A
{
abstract public void sayHello();
}

class Outer
{
public static void main(String[] args)
{
new Outer().callInner(new A()
{
public void sayHello()
{
System.out.println(this); // the object created from the anonymous Inner
System.out.println("Hello!");
}
});
}

public void callInner(A a)
{
a.sayHello();
}
}

4、靜態內部類
和非靜態內部類相比,區別就在於靜態內部類沒有了指向外部類的引用。除此之外,在任何非靜態內部類中,都不能有靜態數據,靜態方法或者又一個靜態內部類(內部類的嵌套可以不止一層)。不過靜態內部類中卻可以擁有這一切。這也算是兩者的第二個區別吧。一個靜態的內部類,才可以聲明一個static成員,靜態內部類可以訪問外圍類的靜態方法、成員(包括private static的成員)。靜態內部類實例化的時候不必先實例化外圍類,可以直接實例化內部類。而對於非靜態內部類則必須先實例化其外部類,才能再實例化本身。

5.內部類的繼承
當一個類繼承自一個內部類時,預設的構造器不可用。必須使用如下語法:
class WithInner
{
class Inner
{
public void sayHello()
{
System.out.println("Hello.");
}
}
}

public class Test extends WithInner.Inner
{
Test(WithInner wi)
{
wi.super();
}
public static void main(String[] args)
{
WithInner wi=new WithInner();
Test test=new Test(wi);
test.sayHello();
}
}
因為每一個內部類都有一個指向外部類的引用,在繼承一個內部類,必須先創建一個外部類,通過這個外部類引用來調用其內部類的構造方法。如果繼承的內部類是一個靜態內部類,則就不需要這樣,直接super()調用即可;

6、內部類的2種特殊用法
一個類從另一個類派生出來,又要實現一個介面。但在介面中定義的方法與父類中定義的方法的意義不同,則可以利用內部類來解決這個問題。
interface Machine
{
void run();
}

class Person
{
void run()
{
System.out.println("run");
}
}

class Robot extends Person
{
private class MachineHeart implements Machine
{
public void run()
{
System.out.println("heart run");
}
}

Machine getMachine()
{
return new MachineHeart();
}
}

class Test
{
public static void main(String[] args)
{
Robot robot = new Robot();
Machine m = robot.getMachine();
m.run();
robot.run();
}
}
在Robot類內部使用內部類MachineHeart來實現介面Machine的run方法。同時Robot類又繼承了父類Person的run方法。如果不使用內部類MachineHeart而使Robot直接實現介面Machine,則該如何調用父類的run方法?

利用內部類可解決c++中多重繼承所解決的問題
class A
{
void fn1()
{
System.out.println("It' s fn1.");
}
}

abstract class B
{
abstract void fn2();
}

class C extends A
{
B getB()
{
return new B()
{
public void fn2()
{
System.out.println("It' s fn2.");
}
};
}
}

class Test
{
public static void main(String[] args)
{
C c = new C();
c.fn1();
c.getB().fn2();
}
}
類C既要繼承類A又要繼承類B,則可將類B的定義放入類C內部,使之成為內部類。

一般情況下 當我們需要在某一情形下實現一個介面,而在另一情形下又不需要實現這個介面時,我們可以使用內部類來解決這一問題。讓內部類來實現這個介面。另外一個很好的理由是java內部類加上介面可以有效地實現多重繼承。

⑽ 編譯時和運行時對象分別是什麼數據類型

編譯時被當做NSString 的實例來處理,運行時其isa指向的是[NSData Class],故運行時該實例只能收到NSData的固有實例方法(或者自己寫的Category),如果對該實例發送諸如 testObject stringByAppendingString:@"哈哈哈" ,編譯時不會報錯只會給出黃色警告,但是運行時會直接崩潰,錯誤信息可能是
-[_NSZeroData stringByAppendingString:]: unrecognized selector sent to instance 0x8946440
故可以看出NSData 在運行時的真實類型是_NSZeroData(這里用的NSData alloc init,這里是個空的NSData,所以是ZeroData,不是說所有的)
如果對該實例發送諸如 testObject
::這類消息 編譯器會直接給出紅色錯誤,無法運行,但其實這個實例是有這個方法的。
這里如果改為 id testObject=[[NSData alloc]init];
那麼發送NSString 的方法仍然會崩潰,發送NSData的實例方法則完全正常。並且兩種情況編譯器都不會再給出警告或錯誤。

閱讀全文

與編譯時的數據對象相關的資料

熱點內容
51單片機引腳圖電路 瀏覽:214
麥當勞員工怎麼登錄app 瀏覽:530
目前什麼系統編程語言最好 瀏覽:488
破曉傳說未加密 瀏覽:450
農信app裡面怎麼查收款明細 瀏覽:261
android列印小票 瀏覽:168
小程序支付php 瀏覽:609
oppo手機文件夾紅色 瀏覽:486
android權威編程源碼 瀏覽:601
搜索引擎指標源碼 瀏覽:63
片場app怎麼樣 瀏覽:915
ctcpip編程 瀏覽:522
java統計字元串次數 瀏覽:256
中興交換機zxr10vlan配置命令 瀏覽:829
java面試spring 瀏覽:151
得物程序員加班厲害嗎 瀏覽:958
h1z1東京伺服器地址 瀏覽:397
海賊王一番賞文件夾什麼樣 瀏覽:847
24bit高頻精品解壓音樂 瀏覽:182
api程序員遇到更新 瀏覽:299