初始化
這里的主要內容是
初始化
相關的內容,其中還會穿插其他的內容
- 構造器初始化
- 靜態數據初始化
- 顯示的靜態初始化
- 非靜態實例初始化
穿插內容
- 構造器
- 方法重載
- this關鍵字
- static 關鍵字
構造器初始化
構造器
構造器是在創建對象時被調用的特殊方法。(構造器是一個方法只不過它是特殊的),之所以特殊是因為構造器沒有返回值。與返回空(void)不同。一個簡單的說法,普通方法就算是void,還是可以掉的,但構造器沒得改。構造器是一個靜態的方法,
構造器中的方法名與它所在的類名相同。這是因為為了讓編譯器能夠知道該調用那個方法。在創建對象時,編譯器將為對象分配存儲空間,並調用相應的構造器,這保證了你在操作對象之前,恰當的初始化了。
public class Apple {
// 默認構造器
Apple(){
System.out.println("Hello Word");
}
}
class Test{
public static void main(String[] args){
Apple apple = new Apple();
}
}
沒有參數出入的構造器叫默認構造器,術語是無參構造器,有參數的叫有參構造器。
public class Apple {
//有參構造器
Apple(String a){
System.out.println(a);
}
}
class Test{
public static void main(String[] args){
Apple apple = new Apple("Hello Word");
}
}
如果 Apple(String)
是類里唯一一個構造器,那么你在創建對象時必須傳入參數。
注意:在java中初始與創建是捆綁在一起的,二者不能分離
默認構造器在沒有其它的構造器時,編譯器會自動創建一個默認構造器,如果類中有了構造器(無論是否有參數),編譯器就不會自動創建了。如果沒有構造器,就無法創建對象。
像下邊這么寫就會編譯器會報錯,因為 編譯器沒有找到 new Apple();
沒有參數的構造器
public class Apple {
Apple(String a){
System.out.println(a);
}
public void t(){
return;
}
}
class Test{
public static void main(String[] args){
Apple apple = new Apple();
}
}
像下邊加一個無參構造器即可。
public class Apple {
Apple(){
System.out.println("Hello Word");
}
Apple(String a){
System.out.println(a);
}
public void t(){
return;
}
}
class Test{
public static void main(String[] args){
Apple apple = new Apple();
}
}
在上邊的 Apple
類中,兩個構造器它們名字相同,傳入的參數不同,這種寫法叫 方法重載
,在普通方法中也同樣適用
方法重載
方法重載就好比相同的詞可以表達不同的含義,重載方法名字要相同其中一個重要原因是因為構造器,的名字要與類名相同,這樣只有一個構造器名,就可用多種方式創建一個對象。普通方法的重載也和構造器一樣。
public class Apple {
/* 重載構造器 */
Apple(){
}
Apple(String name){
}
Apple(String name, Integer num){
}
Apple(Integer num, String name){
}
/* 重載的方法 */
/**
* 獲取蘋果
*/
public void getApple(){
}
/**
* 獲取特定品種的蘋果
* @param type 品種
*/
public void getApple(String type){
}
/**
* 獲取特定品種,即某一數量的蘋果
* @param type 蘋果品種
* @param num 蘋果數量
*/
public void getApple(String type, Integer num){
}
/**
* 獲取特定品種,即某一數量的蘋果
* @param num 蘋果品種
* @param type 蘋果數量
*/
public void getApple(Integer num, String type){
}
}
java區分方法名相同的方法,是根據每個方法的獨一無二的參數列表去區分的。
如下這種情況雖然java允許 ,也最好不要用,因為會使得程序難以維護
Apple(String name, Integer num){
}
Apple(Integer num, String name){
}
/**
* 獲取特定品種,即某一數量的蘋果
* @param type 蘋果品種
* @param num 蘋果數量
*/
public void getApple(String type, Integer num){
}
/**
* 獲取特定品種,即某一數量的蘋果
* @param num 蘋果品種
* @param type 蘋果數量
*/
public void getApple(Integer num, String type){
}
拓展:java為什么不用返回區重載方法。
有的時候並不需要一個方法返回東西,只需要方法本身的作用。
public void test(){
a();
}
public void test(String name){
b(name);
}
this 關鍵字
this關鍵字只能在方法內部使用,表示“調用方法的那個對象”。比如在Apple類的后一個方法中使用了this,this代表的就是Apple類。
public class Apple {
public void getApple(){
}
public void juice(){
this.getApple();
}
}
注意:在上邊的 juice() 方法中有調用,同一個類中的方法 getApple() ,在這里是沒有必要加 this的,因為編譯器會自動幫忙加上。雖然手動加也可以,不過高級語言之所以高級,其中一個原因就是它可以幫助我們省略一些重復的事情。
只用當需要指明當前對象時才需要使用 this
public class AppleNum {
private int appleNum = 0;
public AppleNum sumAppleNum(){
appleNum ++;
return this;
}
public void print(){
System.out.println("總和:" + appleNum);
}
public static void main(String[] args) {
AppleNum appleNum = new AppleNum();
appleNum.sumAppleNum().sumAppleNum().sumAppleNum().print();
}
}
如上代碼 sumAppleNum() 方法返回的 appleNum 對象的引用,從而使得可以循環調用 sumAppleNum() 方法。
this 可以有參數列表用於構造器調用構造器,構造器不能使用方法名調用構造器,也不能在普通方法普通方法中。在同一個構造其中 this只能調用一個構造器。
AppleNum(){
this("a");
}
AppleNum(String type){
this(3);
}
AppleNum(Integer i){
}
public AppleNum sumAppleNum(){
// this(3) 編譯器會報錯
}
成員初始化
如果類中的基本類型字段沒有初始化,那java會為他們賦上默認值
public class Apple {
boolean t ;
char c;
byte b;
short s;
int i;
long l;
float f;
double d;
Apple apple;
public void get(){
System.out.println(t);
System.out.println(c);
System.out.println(b);
System.out.println(s);
System.out.println(i);
System.out.println(l);
System.out.println(f);
System.out.println(d);
System.out.println(apple);
}
public static void main(String[] args) {
Apple apple = new Apple();
apple.get();
}
}
從上邊代碼可以看出,基本類型變量沒賦值,java會默認賦上初始值。對象賦上 null
,初始化的順序,影響着程序的正確性。
靜態數據初始化
除非用 new 創建對象,否則實際上並未獲得任何對象。如果不想創建對象也能調用某一方法或屬性,就可以使用static 關鍵字。當聲明一個事物是 static
時,就意味着這個域或方法不會它所在的類的對象實例關聯在一起。
static關鍵字
加上了 static
關鍵字,即為靜態成員變量。
public class Apple {
static int i = 1;
public static void get(){
}
public static void main(String[] args) {
Apple.get();
int num = Apple.i;
}
}
上邊展示了 static 關鍵字的基本用法,不用 new 對象也可以調用方法,雖然不用創建對象也可以調用方法,並不是說每個方法都加上 static
, 如果你的代碼是這樣,那你就得考慮一些你代碼的設計問題了。
下邊是加了 static
,與沒加 static
的區別
public class Apple {
static int i = 1;
int b = 2;
public void get() {
System.out.println(i);
System.out.println(b);
}
public void set(int b){
// 這里因為入參的名字,與字段名相同 一般使用 this 將其區分
this.b = b;
}
public static void main(String[] args) {
Apple a = new Apple();
Apple b = new Apple();
a.get();
b.get();
/*====*/
System.out.println(" /*====*/ ");
Apple.i = 10;
b.set(3);
a.set(4);
a.get();
b.get();
}
}
通過上邊的輸出返現 , a b 兩個對象在輸出 i 時是相同的,a.i b.i指向了同一個內存地址。這也說明多了無論創建多少對象,靜態數據都只占一份存儲區域。
靜態初始化只有在必要時刻才會進行,例如,如果創建 Apple 對象 或者 不調用 Apple.i 那靜態的 i 永遠不會被創建出來。
關鍵字 this
不可以在靜態方法中使用。關鍵字 this
代表的是對象的引用,而靜態方法不依賴於類的具體對象。
顯示的靜態初始化
多個靜態初始化,可以簡化成一個靜態塊
public class Apple {
static {
int i;
char a;
Apple c= new Apple()
}
}
上邊這么寫,因為是在大括號里,意味着是局部變量除非將對象返回出去,否則外邊的方法,里邊的屬性
public class Apple {
Apple c;
static {
c = new Apple();
}
}
非靜態實例初始化
非靜態實例初始化,看起來和靜態塊非常像,區別就是沒有 static
關鍵字
public class Apple {
Apple c;
{
int i;
char a;
c = new Apple();
}
}
這個寫法的非靜態初始化主要是為了匿名內部類准備的。這保證了不管調用那個構造器這部分代碼都會被自行
public class Apple {
Apple(){
System.out.println("5");
}
{
System.out.println("2");
}
static {
System.out.println("1");
}
{
System.out.println("4");
}
{
System.out.println("3");
}
public static void main(String[] args) {
Apple apple = new Apple();
}
}
從上邊的代碼運行輸出可以看出,靜態塊先被執行,然后是非靜態塊,最后是,構造器
靜態初始化塊只在類第一次被加載時執行,非靜態初始化塊在每次創建對象時執行一次,因此創建了多少個對象,就會執行多少次非靜態初始化塊。