------ android培訓、java培訓、期待與您交流! ----------
一、new關鍵字
以”Person p = new Person( )”為例,創建一個對象都在內存中做了什么事情?
1:先將硬盤上指定位置的Person.class文件加載進內存。
2:執行main方法時,在棧內存中開辟了main方法的空間(壓棧-進棧),然后在main方法的棧區分配了一個變量p。
3:在堆內存中開辟一個實體空間,分配了一個內存首地址值。
4:在該實體空間中進行屬性的空間分配,並進行了默認初始化。
5:對空間中的屬性進行顯示初始化。
6:進行實體的構造代碼塊初始化。
7:調用該實體對應的構造函數,進行構造函數初始化。
8:將首地址賦值給p ,p變量就引用了該實體。(指向了該對象)
二、this關鍵字
this 關鍵字指的是當前調用的對象,如果有100 個對象,將有100 個this 對象指向各個對象
this 關鍵字可以使用在:
①當局部變量和成員變量重名的時候可以使用this 指定調用成員變量;②通過this 調用另一個構造方法。
以下為具體實例:
1.當局部變量和成員變量重名的時候可以使用this 指定調用成員變量
<span style="font-size:18px;">public class OOTest09 {
public static void main(String[] args) {
Student zhangsan = new Student();
zhangsan.setId(1001);
zhangsan.setName("張三");
zhangsan.setSex(true);
zhangsan.setAddress("北京");
zhangsan.setAge(20);
System.out.println("id=" + zhangsan.getId());
System.out.println("name=" + zhangsan.getName());
System.out.println("sex=" + zhangsan.getSex());
System.out.println("address=" + zhangsan.getAddress());
System.out.println("age=" + zhangsan.getAge());
}
}
class Student {
// 學號
private int id;
// 姓名
private String name;
// 性別
private boolean sex;
// 地址
private String address;
// 年齡
private int age;
// 設置學號
public void setId(int id) {
this.id = id;
}
// 讀取學號
public int getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setSex(boolean sex) {
this.sex = sex;
}
public boolean getSex() {
return sex;
}
public void setAddress(String address) {
this.address = address;
}
public String getAddress() {
return address;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}</span>
通過this 可以取得當前調用對象,采用this 明確指定了成員變量的名稱,所以就不會賦值到局部變量,這里涉及到了狹義和廣義上的javabean 概念,在這里不詳述。
2.通過this 調用另一個構造方法
①通過new 調用當前對象的構造函數(注意這樣是不對的)
<span style="font-size:18px;">public class OOTest10 {
public static void main(String[] args) {
// Student zhangsan = new Student(1001, "張三", true, "北京", 20);
// Student zhangsan = new Student(1001, "張三");
Student zhangsan = new Student(1002, "李四");
System.out.println("id=" + zhangsan.getId());
System.out.println("name=" + zhangsan.getName());
System.out.println("sex=" + zhangsan.getSex());
System.out.println("address=" + zhangsan.getAddress());
System.out.println("age=" + zhangsan.getAge());
}
}
class Student {
// 學號
private int id;
// 姓名
private String name;
// 性別
private boolean sex;
// 地址
private String address;
// 年齡
private int age;
public Student(int id, String name) {
/*
* this.id = id; this.name = name; this.sex=true; this.address="北京";
* this.age=20;
*/
// 調用構造函數,部分值采用默認值
new Student(id, name, true, "北京", 20);
}
public Student(int id, String name, boolean sex, String address, int age) {
this.id = id;
this.name = name;
this.sex = sex;
this.address = address;
this.age = age;
}
// 設置學號
public void setId(int studentId) {
id = studentId;
}
// 讀取學號
public int getId() {
return id;
}
public void setName(String studentName) {
name = studentName;
}
public String getName() {
return name;
}
public void setSex(boolean studentSex) {
sex = studentSex;
}
public boolean getSex() {
return sex;
}
public void setAddress(String studentAddress) {
address = studentAddress;
}
public String getAddress() {
return address;
}
public void setAge(int studentAge) {
if (studentAge >= 0 && studentAge <= 120) {
age = studentAge;
}
}
public int getAge() {
return age;
}
}</span>
②通過this 調用當前對象的構造函數
<span style="font-size:18px;">public class OOTest11 {
public static void main(String[] args) {
Student zhangsan = new Student(1002, "李四");
System.out.println("id=" + zhangsan.getId());
System.out.println("name=" + zhangsan.getName());
System.out.println("sex=" + zhangsan.getSex());
System.out.println("address=" + zhangsan.getAddress());
System.out.println("age=" + zhangsan.getAge());
}
}
class Student {
// 學號
private int id;
// 姓名
private String name;
// 性別
private boolean sex;
// 地址
private String address;
// 年齡
private int age;
public Student(int id, String name) {
/*
* this.id = id; this.name = name; this.sex=true; this.address="北京";
* this.age=20;
*/
// 調用構造函數,部分值采用默認值
// new Student(id, name, true, "北京", 20);
// 采用this 調用當前對象對象的構造函數,不能采用new,以上調用是錯誤的
this(id, name, true, "北京", 20);
}
public Student(int id, String name, boolean sex, String address, int age) {
this.id = id;
this.name = name;
this.sex = sex;
this.address = address;
this.age = age;
}
// 設置學號
public void setId(int studentId) {
id = studentId;
}
// 讀取學號
public int getId() {
return id;
}
public void setName(String studentName) {
name = studentName;
}
public String getName() {
return name;
}
public void setSex(boolean studentSex) {
sex = studentSex;
}
public boolean getSex() {
return sex;
}
public void setAddress(String studentAddress) {
address = studentAddress;
}
public String getAddress() {
return address;
}
public void setAge(int studentAge) {
if (studentAge >= 0 && studentAge <= 120) {
age = studentAge;
}
}
public int getAge() {
return age;
}
}</span>
注意:用this調用構造函數,必須定義在構造函數的第一行。因為構造函數是用於初始化的,所以初始化動作一定要執行。否則編譯失敗。
三、Static關鍵字
1、特點
①static 修飾符可以修飾:變量、方法和代碼塊
②想要實現對象中的共性數據的對象共享。可以將這個數據進行靜態修飾。
③被靜態修飾的成員,可以直接被類名所調用。也就是說,靜態的成員多了一種調用方式。類名.靜態方式。
④靜態隨着類的加載而加載。而且優先於對象存在。
2、弊端
①有些數據是對象特有的數據,是不可以被靜態修飾的。因為那樣的話,特有數據會變成對象的共享數據。這樣對事物的描述就出了問題。所以,在定義靜態時,必須要明確,這個數據是否是被對象所共享的。
②靜態方法只能訪問靜態成員,不可以訪問非靜態成員。
因為靜態方法加載時,優先於對象存在,所以沒有辦法訪問對象中的成員。
③靜態方法中不能使用this,super關鍵字。
因為this代表對象,而靜態在時,有可能沒有對象,所以this無法使用。
④主函數是靜態的。
3、成員變量和靜態變量的區別
①成員變量所屬於對象,所以也稱為實例變量;靜態變量所屬於類,所以也稱為類變量。
②成員變量存在於堆內存中,靜態變量存在於方法區中。
③成員變量隨着對象創建而存在,隨着對象被回收而消失;靜態變量隨着類的加載而存在,隨着類的消失而消失。
④成員變量只能被對象所調用 ,靜態變量可以被對象調用,也可以被類名調用。
所以,成員變量可以稱為對象的特有數據,靜態變量稱為對象的共享數據。
那么什么時候定義靜態成員呢?或者說:定義成員時,到底需不需要被靜態修飾呢?
成員分兩種:
①成員變量。(數據共享時靜態化)
該成員變量的數據是否是所有對象都一樣?如果是,那么該變量需要被靜態修飾,因為是共享的數據。 如果不是,那么就說這是對象的特有數據,要存儲到對象中。
②成員函數。(方法中沒有調用特有數據時就定義成靜態)
如何判斷成員函數是否需要被靜態修飾呢?
只要參考該函數內是否訪問了對象中的特有數據即可:如果有訪問特有數據,那方法不能被靜態修飾,如果沒有訪問過特有數據,那么這個方法需要被靜態修飾。
4、注意事項
①靜態的生命周期很長;②靜態代碼塊只執行一次(new 多個對象就只執行一次)。③靜態代碼塊、構造代碼塊、構造函數同時存在時的執行順序:靜態代碼塊——構造代碼塊——構造函數。④靜態代碼塊如果和主函數在同一類中,優先於主函數執行。
5、關於主函數的說明
Public:訪問權限最大。
static:不需要對象,直接類名即可。
void:主函數沒有返回值。
Main:主函數特定的名稱。
(String[] args):主函數的參數,是一個字符串數組類型的參數,jvm調用main方法時,傳遞的實際參數是 new String[0]。
jvm默認傳遞的是長度為0的字符串數組,我們在運行該類時,也可以指定具體的參數進行傳遞。可以在控制台,運行該類時,在后面加入參數。參數之間通過空格隔開。jvm會自動將這些字符串參數作為args數組中的元素,進行存儲。
四、單例模式初步
設計模式是可以重復利用的解決方案,設計模式的提出是在1995 年,是由4 位作者提出的,稱為GoF,也就是“四人組”提出的。
設計模式從結構上分為三類:創建型、結構性、行為型。
其中最簡單的設計模式就是單例了,單例這種模式,盡量少用,也有將其稱為“反模式”。
我們知道對象實例創建完成后,會放到堆中,如果堆中的實例過多,將會存在特別多的垃圾,這樣會導致一些問題,如內存溢出等,使用單例模式后,只會創建一個實例,顯著減少對象實例的個數,同時也會提高性能,因為不會頻繁的創建對象,這只是他的一個好處,初學者只需要了解這方面即可。
單例模式的三要素:
①在類體中需要具有靜態的私有的本類型的變量;
②構造方法必須是私有的;
③提供一個公共的靜態的入口點方法。
<span style="font-size:18px;">public class SingletonPatternTest01 {
public static void main(String[] args) {
// Singleton s1 = new Singleton();
// Singleton s2 = new Singleton();
// ............
Singleton.getInstance().test();
}
}
class Singleton {
// 靜態私有的本類的成員變量
private static Singleton instance = new Singleton();
// 私有的構造方法
private Singleton() {
}
// 提供一個公共的靜態的入口點方法
public static Singleton getInstance() {
return instance;
}
public void test() {
System.out.println("----------test----------");
}
}</span>
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。