成員變量和局部變量的區(qū)別
1、在類中的位置不同
- 成員變量 類中方法外
- 局部變量 方法內(nèi)或者方法聲明上
2、在內(nèi)存中的位置不同
- 成員變量 堆內(nèi)存
- 局部變量 棧內(nèi)存
(局部變量:在方法定義中或者方法聲明上的變量都稱為局部變量)
注:
java程序為了提高程序的效率,就對數(shù)據(jù)進行了不同空間的分配,具體的是劃分了如下幾個空間
棧:存放的是局部變量
堆:存放的是所有new出來的東西
(堆內(nèi)存的特點:
A 每一個new出來的對象都有地址值
B 每個變量都有默認值
byte int short long 0
float double 0.0
char \u000
boolean true false
引用類型 null
C 使用完畢就變成了垃圾,但不會立即回收,會在垃圾回收器空閑的時候回收 )
方法區(qū):專門存放方法的地方
本地方法區(qū)(和系統(tǒng)有關(guān)):
寄存器:(CPU使用)

3、生命周期不同
- 成員變量 隨著對象的存在而存在,隨著對象的消失而消失
- 局部變量 隨著方法的調(diào)用而存在,隨著方法的調(diào)用完畢而消失
4、初始值不同
- 成員變量 有默認的初始值
- 局部變量 沒有默認的初始值,只能先定義,賦值才能使用
package mianxiangduixaing02;
/*成員變量和局部變量的區(qū)別
A 在類中的位置不同
成員變量 類中方法外
局部變量 方法內(nèi)或者方法聲明上
B 在內(nèi)存中的位置不同
成員變量 堆內(nèi)存
局部變量 棧內(nèi)存
C 生命周期不同
成員變量 隨著對象的存在而存在,隨著對象的消失而消失
局部變量 隨著方法的調(diào)用而存在,隨著方法的調(diào)用完畢而消失
D 初始值不同
成員變量 有默認的初始值
局部變量 沒有默認的初始值,只能先定義,賦值才能使用
*/
public class Variable {
//成員變量
int num = 10;
public void show(){
//局部變量
int num2=20;
}
}
package mianxiangduixaing02;
public class variabledemo {
//不同方法中是不能訪問另一個方法內(nèi)的變量
public static void main(String[] args){
Variable v = new Variable();
System.out.println(v.num);//訪問成員變量
}
}
結(jié)果為10
public static void main(String[] args){
Variable v = new Variable();
System.out.println(v.num2);//訪問局部變量error
//只能訪問成員變量,訪問局部變量會報錯
}
}
public class Variable {
//成員變量
int num;//不給num賦值
public void show(){
//局部變量
//int num2; 不給num2賦值,就沒有默認初始值
int num2 = 20;
System.out.println(num2);
}
}
public static void main(String[] args){
Variable v = new Variable();
System.out.println(v.num);//訪問成員變量
v.show();//訪問show方法
}
}
結(jié)果為10、20
方法的形式參數(shù)是類名的時候如何調(diào)用
什么是形式參數(shù),什么是實際參數(shù)???
- 形式參數(shù):就是在定義函數(shù)或過程的時候命名的參數(shù)。通俗講就是一個記號。
- 實際參數(shù):就是在執(zhí)行時,調(diào)用函數(shù)或過程時,傳遞給函數(shù)或過程的參數(shù)。通俗講就是實際值。
- 參數(shù)嘛,就是一個可變量,它隨著使用者的不同而發(fā)生變化。舉個例子,在中學的時候?qū)W過sin(x)函數(shù),這里的x就是形式參數(shù),當你需要求1的正弦值時,你會使用sin(1),這里的1就是實際參數(shù)。
- 形參和實參間的關(guān)系:兩者是在調(diào)用的時候進行結(jié)合的,通常實參會將取值
什么是基本類型,什么是引用類型???
java中的數(shù)據(jù)類型分為兩大類:基本數(shù)據(jù)類型和引用數(shù)據(jù)類型
基本數(shù)據(jù)類型,包括數(shù)值型,字符型和布爾型。
數(shù)值型:1)整型:byte 1個字節(jié);short 2個字節(jié);int 4個字節(jié);long 8個字節(jié)。
浮點型:float 4個字節(jié);double
8個字節(jié);可以采用十進制和十六進制兩種表示方式,其中十六進制表示方法只能采用科學計數(shù)法,例如:0x1.2p3,表示的是的是1乘以16加上2乘以16的-1次方的和乘以2的三次方;浮點型的默認類型為DOUBLE型,如果聲明float型浮點數(shù),要在數(shù)值后面加上f或F,例如:float
f1 = 3.14F;否則會報精度錯誤。字符型:char 采用unicod的16位編碼方式進行編碼。
布爾型:true,false;
引用數(shù)據(jù)類型:類、接口類型、數(shù)組類型、枚舉類型、注解類型;
基本數(shù)據(jù)類型和引用數(shù)據(jù)類型的區(qū)別主要在存儲方式上:
基本數(shù)據(jù)類型在被創(chuàng)建時,在棧上給其劃分一塊內(nèi)存,將數(shù)值直接存儲在棧上;
引用數(shù)據(jù)類型在被床架時,首先要在棧上給其引用(句柄)分配一塊內(nèi)存,而對象的具體信息都存儲在堆內(nèi)存上,然后由棧上面的引用指向堆中對象的地址。
形式參數(shù)的問題
- 基本類型:形式參數(shù)的改變不影響實際參數(shù)
- 引用類型:形式參數(shù)的改變直接影響實際參數(shù)
例1:形式參數(shù)是基本類型時
package mianxiangduixaing02;
public class xingshicanshu{
public int sum(int a,int b)//形式參數(shù),參數(shù)是基本類型
{
return a+b;
}
}
package mianxiangduixaing02;
public class xingshicanshudemo {
public static void main(String[] args) {
xingshicanshu x = new xingshicanshu();
//x.sum(10, 20); 無結(jié)果,會報錯,不能直接調(diào)用
//為什么不能直接調(diào)用??
int result = x.sum(10, 20);
System.out.println("result:"+result);
}
}
結(jié)果為30
例2:形式參數(shù)是引用類型時
package mianxiangduixaing02;
public class student {
public void show() {
System.out.println("我愛學習");
}
}
package mianxiangduixaing02;
public class studentdemo {
//如果看到一個方法的形式參數(shù)是一個類類型(引用類型),這里其實需要的就是該類的對象
public void method(student s)//形式參數(shù)是引用類型
{//調(diào)用的時候,把main方法中的地址傳遞到了這里 student s = new student()
s.show();
}
}
package mianxiangduixaing02;
public class test {
public static void main(String[] args) {
//形式參數(shù)是引用類型時的調(diào)用
//需求:調(diào)用studentdemo類中的method方法
studentdemo sd = new studentdemo();
//創(chuàng)建學生對象
student s = new student();
sd.method(s);//把s的地址值給到了這里
}
}
結(jié)果為“我愛學習”
匿名對象的概述和應用
匿名對像:
就是沒有名字的對象(是對象的一種簡化表達形式)
匿名對像的倆種使用情況:
對象調(diào)用方法僅僅是一次的時候
作為實際參數(shù)傳參的時候
package mianxiangduixaing02;
public class test {
public static void main(String[] args) {
//形式參數(shù)是引用類型時的調(diào)用
//需求:調(diào)用studentdemo類中的method方法
studentdemo sd = new studentdemo();
//創(chuàng)建學生對象
student s = new student();
sd.method(s);//把s的地址值給到了這里
//匿名對像
new student();//只是創(chuàng)建出一個對象,并沒有調(diào)用,所以不出結(jié)果值
//匿名對像調(diào)用方法
new student().show();
System.out.println("-----------------");
//為什么僅僅只能調(diào)用一次?
sd.method(s);
sd.method(s);//這表示同一個對象調(diào)用了倆次方法
new student().show();
new student().show();//這表示重新創(chuàng)建了一個對象,所以多次調(diào)用的時候不適合
}
}
結(jié)果為:
我愛學習
我愛學習
-----------------
我愛學習
我愛學習
我愛學習
我愛學習
匿名對像調(diào)用的好處是什么?
A 匿名對像調(diào)用完畢后就是垃圾,可以被垃圾回收站回收
B 匿名對像可以作為實際參數(shù)傳遞
//匿名對像可以作為實際參數(shù)傳遞
sd.method(new student());
結(jié)果為:我愛學習
private關(guān)鍵字的概述和特點
封裝概述
- 是指隱藏對象的屬性和實現(xiàn)細節(jié),僅對外提供公共的訪問方式
好處
- 隱藏實現(xiàn)細節(jié),提供公共訪問方式
- 提高了代碼的復用性
- 提高安全性
封裝原則
- 將不需要對外提供的內(nèi)容都隱藏起來
- 把屬性隱藏,提供公共方法對其訪問
private關(guān)鍵字
- 是一個權(quán)限修飾符(只有自己可以訪問)
- 可以修飾成員(成員變量和成員方法)
- 被private修飾的成員只能在本類中被訪問
private最常見的應用
- 把成員變量用private修飾
- 提供對應的getxxx()和ssetxxx()方法
被private修飾后權(quán)限很小,只能自己訪問
案例
package mianxiangduixaing02;
public class privatedemo {
//int num = 10;(1)
private int num = 20;//(2)
public void show(){
System.out.println(num);
}
private void method(){
System.out.println("method");
}
public void show2(){
method();
}
}
package mianxiangduixaing02;
public class privatetest {
public static void main(String[] args) {
privatedemo pd = new privatedemo();
//System.out.println(pd.num);(1)
pd.show();//(2)
pd.show2();
}
}
num第一種定義為int類,測試類中可以直接訪問num,得出結(jié)果10
num第二種定義為private類,測試類中不可以直接訪問,在privatedemo類中定義了一個公共的show方法,
然后在此方法中輸出被定義為private類的num,在測試類中創(chuàng)建的對象調(diào)用show方法,得出結(jié)果20,
同理,被private修飾的方法也不能被直接調(diào)用,必須用同類中的一個公共的方法輸出這個方法,
然后在測試類中調(diào)用這個公共的方法,結(jié)果為method
封裝和private應用標準案例
package mianxiangduixaing02;
public class student {
private String name;
private int age;
public String getName(){
return name;
}
public void setName(String n){
name= n;
}
public int getAge(){
return age;
}
public void setAge(int m){
age = m;
}
}
package mianxiangduixaing02;
public class studenttest {
public static void main(String[] args) {
student s = new student();
//System.out.println(s.Name+"---------"s.get);error
System.out.println(s.getName()+"--------"+s.getAge());
//給成員變量賦值
//s.Name="李四";error
//s.age="27";error
//通過方法賦值
s.setName("李四");
s.setAge(27);
System.out.println(s.getName()+"-------"+s.getAge());
}
}
結(jié)果為:null--------0
李四-------27
getXxx()方法為獲取,只能輸出結(jié)果,setXxx()方法為賦值,可以修改前面定義好的數(shù)值,也可以直接用此方法賦值
被private定義得無論是成員變量還是成員方法,都不可以被本類以外的類得到
this關(guān)鍵字的概述和應用
this關(guān)鍵字
- this:代表所在類的對象引用,簡單說,代表當前類的一個對象
- 記住
方法被哪個對象調(diào)用,this就代表那個對象
什么時候使用this呢???
- 局部變量隱藏成員變量
- 其他用法見后面詳解
案例
package mianxiangduixaing02;
//java中起名字要見名知意,單獨的n,a拿出來別人并不知道是什么意思
public class student {
private String name;
private int age;
public String getName(){
return name;
}
/*public void setName(String n){
name= n;
}
*/
public void setName(String name){//name=李四
//name= name;
this.name=name;
}
//所以在這里將n改為name
//但是變量的使用規(guī)則是就近原則,所以這個是有問題的,結(jié)果出來為null 0
//這里的調(diào)用只能用對象名
//這個對象如果存在,它應該代表的就是student類中的一個對象
//那么誰能夠代表當前的對象呢?java就提供了一個關(guān)鍵字 this
//this.name=name;
public int getAge(){
return age;
}
/*public void setAge(int m){
age = m;
}
*/
public void setAge(int age){
//age = age;
this.age=age;
}
//在這里將m改為age
}
package mianxiangduixaing02;
public class studenttest {
public static void main(String[] args) {
student s = new student();
//System.out.println(s.Name+"---------"s.get);error
System.out.println(s.getName()+"--------"+s.getAge());
//給成員變量賦值
//s.Name="李四";error
//s.age="27";error
//通過方法賦值
s.setName("李四");
s.setAge(27);
System.out.println(s.getName()+"-------"+s.getAge());
}
}
結(jié)果為:null--------0
李四-------27
this關(guān)鍵字的內(nèi)存圖解
package mianxiangduixaing02;
public class student1 {
private String name;
private int age;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
}
package mianxiangduixaing02;
public class student1test {
public static void main(String[] args) {
student1 s1 = new student1();//創(chuàng)建第一個對象
s1.setName("李美麗");
s1.setAge(27);
System.out.println(s1.getName()+"--------"+s1.getAge());
student1 s2 = new student1();//創(chuàng)建第二個對象
s2.setName("劉小花");
s2.setAge(18);
System.out.println(s2.getName()+"--------"+s2.getAge());
}
}

注:首先,程序從main方法開始執(zhí)行,創(chuàng)建第一個student1類的對象,然后對象調(diào)setName/setAge方法,程序走到student1類中的setName/setAge方法,將李美麗賦值給name(因為有形參,所以String name就相當于李美麗,this.name=String name=李美麗),然后程序走到類中方法外的成員變量name,當程序輸出s1.getName()的時候,程序走到getName()方法,返回了name(此時的name就是剛才類中方法外的name),返回的name就輸出了,結(jié)果為李美麗,其他同上
構(gòu)造方法的概述與格式
構(gòu)造方法作用概述
- 給對象的數(shù)據(jù)進行初始化
構(gòu)造方法格式
- 方法名與類名相同
- 沒有返回值類型,連void也沒有(修飾符那一塊沒有任何東西)
- 沒有具體的返回值(不需要用return來做什么東西)
構(gòu)造方法的注意事項
- 如果你不提供構(gòu)造方法,系統(tǒng)會給出默認的構(gòu)造方法
- 如果你提供了構(gòu)造方法,系統(tǒng)將不會再給出
- 構(gòu)造方法也是可以重載的
構(gòu)造方法的格式及作用案例
package mianxiangduixaing02;
public class construct {
private String name;//null
private int age;// 0
//系統(tǒng)自動給的初始值,所以構(gòu)造方法的作用就是給成員變量賦默認值
public construct(){//這就是構(gòu)造方法
System.out.println("這是一個構(gòu)造方法");
}
}
package mianxiangduixaing02;
public class constructtest {
public static void main(String[] args) {
construct c = new construct();
char[] s = null;
System.out.println(s);//輸出的是構(gòu)造方法中的內(nèi)容
}
}
構(gòu)造方法的重載及注意事項
方法重載就是方法重寫,構(gòu)造方法重載就是將系統(tǒng)自帶的構(gòu)造方法重寫
我們一直在使用構(gòu)造方法,但是我們卻沒有定義過,那么構(gòu)造方法從哪來呢?
- 構(gòu)造方法的注意事項
- A 如果我們沒有給出構(gòu)造方法,系統(tǒng)將會自動提供一個無參構(gòu)造方法
- B 如果我們給出了構(gòu)造方法,系統(tǒng)將不會提供默認的構(gòu)造方法
- 注:如果這個時候,我們還想用無參構(gòu)造方法,就必須自己定義,建議自己定義無參構(gòu)造方法
- 給成員賦值有倆種方法
- A setXxx()方法
- B 構(gòu)造方法
public class con
package mianxiangduixaing02;
struct {
private String name;
private int age;
public construct(){
System.out.println("這是無參構(gòu)造方法");
}
public construct(String name){
System.out.println("這是帶一個String類型的構(gòu)造方法");
this.name = name;
}
public construct(int age){
System.out.println("這是帶一個int類型的構(gòu)造方法");
this.age = age;
}
public construct(String name,int age){
System.out.println("這是帶一個String,int類型的構(gòu)造方法");
this.name = name;
this.age = age;
}
public void show(){
System.out.println(name+"-------"+age);
}
}
package mianxiangduixaing02;
public class constructtest {
public static void main(String[] args) {
//創(chuàng)建對象1
construct c1 = new construct();
c1.show();
//創(chuàng)建對象2
construct c2 = new construct("李美麗");
c2.show();
//創(chuàng)建對象3
construct c3 = new construct(18);
c3.show();
//創(chuàng)建對象4
construct c4 = new construct("李美麗"+18);
c4.show();
}
}
結(jié)果為:
null-------0
這是帶一個String類型的構(gòu)造方法
李美麗-------0
這是帶一個int類型的構(gòu)造方法
null-------18
這是帶一個String類型的構(gòu)造方法
李美麗18-------0
成員方法的分類及使用
類的成員方法分類
根據(jù)返回值
- 有明確返回值類型
- 返回void類型的方法(無返回值類型)
根據(jù)形式參數(shù)
- 無參方法
- 帶參方法
類的組成:成員變量、構(gòu)造方法、成員方法
package mianxiangduixaing02;
public class student2 {
public String getString1(){//無參有返回值類型
return "hello1";
}
public void getString2(){//無參無返回值類型
System.out.println("hello2");
}
public String getString3(String name){//帶參有返回值類型
return name;
}
public void getString4(String name){//帶參無返回值類型
System.out.println(name);
}
}
package mianxiangduixaing02;
public class student2test {
public static void main(String[] args) {
student2 s= new student2();
//調(diào)用無參有返回值類型
String result = s.getString1();
System.out.println(result);
//調(diào)用無參無返回值類型
s.getString2();
//調(diào)用帶參有返回值類型
String result2 = s.getString3("hello3");
System.out.println(result2);
//調(diào)用帶參無返回值類型
s.getString4("hello4");
}
}
結(jié)果為:
hello1
hello2
hello3
hello4
創(chuàng)建對象時做了哪些事情
student s = new student();在內(nèi)存中做了哪些事情?
- 加載student class文件進內(nèi)存
- 在棧內(nèi)存為s開辟內(nèi)存空間
- 在堆內(nèi)存為學生對象開辟內(nèi)存空間
- 對學生對象的成員變量進行默認初始化
- 對學生對象的成員變量進行顯示初始化
- 通過構(gòu)造方法對學生對象的成員變量賦值
- 學生對象初始化完畢,把對象地址賦值給s變量
student 類案例及內(nèi)存圖解
package mianxiangduixaing02;
public class student3 {
private String name = "李美麗";//原本默認初始值為null
private int age = 27;//原本默認初始值為0
//在這里操作者手動給了值,name和age就變成了李美麗27//顯示初始化
public student3(){//構(gòu)造方法給成員變量賦值
name = "李四";
age = 30;
}
}
package mianxiangduixaing02;
public class student3test {
public static void main(String[] args) {
student3 s = new student3();
}
}
結(jié)果:李四 30

static關(guān)鍵字的引入
static關(guān)鍵字
可以修飾成員變量和成員方法
static關(guān)鍵字的特點
- 隨著類的加載而加載
(回想main方法,用static修飾的方法,如果class加載的時候沒有加載main方法,我們使用的時候還能直接用么?不能,所以是隨著類的加載而加載) - 優(yōu)先于對象存在
(對象是在new的時候才出現(xiàn),而它在class文件加載的時候就已經(jīng)出現(xiàn)了) - 被類的所有成員共享(這也是我們判斷是否使用關(guān)鍵字的條件,代碼如下)
- 可以通過類名調(diào)用,其實她本身也可以通過對象名調(diào)用(推薦使用類名調(diào)用)
靜態(tài)修飾的內(nèi)容我們一般稱其為:與類相關(guān)的,類成員
static:靜態(tài)修飾成員變量(static怎么用),詳細如下代碼可見
public class person {
String name;
int age;
//String country;
static String country;
public person(){}
public person(String name,int age){
this.name = name;
this.age = age;
}
public person(String name,int age,String country){
this.name = name;
this.age = age;
this.country = country;
}
public void show(){
System.out.println("name="+name+"--------"+"age="+age+"-------"+"country="+country);
}
}
package mianxiangduixaing02;
public class persontest {
public static void main(String[] args) {
person p1 = new person("李美麗",16,"中國");
p1.show();
person p2 = new person("劉小花",18,"中國");
p2.show();
person p3 = new person("鳳姐",27,"中國");
p3.show();
//三個人,名字和年齡都是不一樣的,但是國籍都為中國,
//每new一次都開辟一次內(nèi)存空間,太浪費內(nèi)存了,所以java就提供了一個關(guān)鍵字 static
//用static修飾country
System.out.println("------------------------------------------------");
person p4 = new person("李美麗",16,"中國");
p4.show();
person p5 = new person("劉小花",18);
p5.show();
person p6 = new person("鳳姐",27);
p6.show();
//在用static定義后,這里只給了p4國籍,其他倆個都沒給
//結(jié)果和上面一樣,都有三個變量顯示
System.out.println("-----------------------------------------------");
p6.country="美國";
p6.show();
p4.show();
p5.show();
//結(jié)果都為美國,因為這些對象共享同一個靜態(tài)修飾的成員
System.out.println(person.country); //通過類名調(diào)成員
}
}
結(jié)果為:
name=李美麗--------age=16-------country=中國
name=劉小花--------age=18-------country=中國
name=鳳姐--------age=27-------country=中國
------------------------------------------------
name=李美麗--------age=16-------country=中國
name=劉小花--------age=18-------country=中國
name=鳳姐--------age=27-------country=中國
-----------------------------------------------
name=鳳姐--------age=27-------country=美國
name=李美麗--------age=16-------country=美國
name=劉小花--------age=18-------country=美國
美國
static關(guān)鍵字的注意事項
- 在靜態(tài)方法中是沒有this關(guān)鍵字的
- 靜態(tài)方法只能訪問靜態(tài)的成員變量和靜態(tài)的成員方法
案例代碼如下
package mianxiangduixaing02;
//static 關(guān)鍵字注意事項
//A 在靜態(tài)方法中是沒有this關(guān)鍵字的 如何理解呢???
//靜態(tài)是隨著類的加載而加載,this是隨著對象的創(chuàng)建而存在
//靜態(tài)比對象先存在
//B 靜態(tài)方法只能訪問靜態(tài)的成員變量和靜態(tài)的成員方法
//靜態(tài)方法
//成員變量:只能訪問靜態(tài)的成員變量
//成員方法:只能訪問靜態(tài)的成員方法
//非靜態(tài)方法
//成員變量:可能是靜態(tài)的,也可能是非靜態(tài)的
//成員方法:可能是靜態(tài)
public class Teacher {
public int num = 10;
public static int num2 = 20;
public void show(){
System.out.println(num);//隱含的告訴你訪問的是成員變量
System.out.println(this.num);//明確的告訴你訪問的是成員變量
System.out.println(num2);
function();
function2();
}
public static void method(){
//System.out.println(num);//error,無法從靜態(tài)上下文中引用非靜態(tài)
System.out.println(num2);
}
public void function(){
}
public static void function2(){
}
}
package mianxiangduixaing02;
public class Teachertest {
public static void main(String[] args) {
Teacher t = new Teacher();
t.show();
t.method();
}
}
結(jié)果為:
10
10
20
20
靜態(tài)變量和成員變量的區(qū)別
所屬不同
- 靜態(tài)變量屬于類,所以也稱為類變量
- 成員變量屬于對象,所以也稱為實例變量(對象變量)
內(nèi)存中的位置不同
- 靜態(tài)變量存儲于方法區(qū)的靜態(tài)區(qū)
- 成員變量存儲于堆內(nèi)存
內(nèi)存出現(xiàn)的時間不同
- 靜態(tài)變量隨著類的加載而加載,隨著類的消失而消失
- 成員變量隨著對象的創(chuàng)建而存在,隨著對象的消失而消失
調(diào)用不同
- 靜態(tài)變量可以通過類名調(diào)用,也可以通過對象調(diào)用
- 成員變量只能通過對象名調(diào)用