原來你是這樣的JAVA[02]-包、傳參、構造器

1、包(package)


在java程序中,一個java源文件稱爲編譯單元,以.java後綴命名。編譯單元內能夠有一個public類,類名必須與文件名相同。注意:每一個編譯單元只能有一個public類。java

在C#中,咱們用命名空間namespace來組織類庫,用using關鍵字導入某個命名空間。Java中有一樣的概念成爲包,關鍵字是package,使用import關鍵字導入包。ide

1.package:
類庫就是一組文件,每一個文件都有一個public類,以及任意數量的非public類。package語句用來指定當前文件所屬的類庫,它必須放在文件開始,除註釋外的第一行代碼。例如:package com.cathy.dto;函數

2.import:
若是想使用某個包中的類,須要使用import導入對響應包的引用。若是導入包中的多個類,可使用import.cathy.dto.*;測試

3.訪問修飾符:this

  • public:修飾的成員任何人均可以使用。
  • private:除了包含該成員的類,其餘類都沒法訪問該成員。
  • protected:繼承訪問權限。

有一點須要注意:在C#中,類中的成員若是不添加訪問修飾符默認是private;可是在Java中若是不提供任何訪問修飾詞,默認是包訪問權限,處於同一個編譯單元中的全部類彼此之間都是自動可訪問的。
spa

2、方法傳參


1.基本類型做爲參數傳遞
八種基本數據類型(byte,short,int,long,double,float,char,boolean)做爲參數傳遞時,傳遞的是值的拷貝。因此,方法中任何操做都不會修改原值。設計

public class PrimitiveDemo {
     public static void main(String[] args) {
         int num = 10;
         change(num);
         System.out.println("main() a=" + num);//10
     }

    private static void change(Integer a) {
         System.out.println("1 change() a=" + a);
         a = 20;
         System.out.println("2 change() a=" + a);
     }
}

運行結果:code

1 change() a=10
2 change() a=20
main() a=10

 

2.對象參數傳遞引用的拷貝
這個地方,在看《JAVA核心技術I》的時候,做者說的是「JAVA程序設計語言老是按值傳遞」,這個描述感受不是太贊同。看了後面的描述:「方法獲得的是對象引用的拷貝,對象引用及其餘拷貝都同時引用同一對象」。大致和我理解的意思是一致的,也就不糾結說法了。
爲方便測試,首先咱們定義一個類Book:對象

class Book {
     private int price;

    public void setPrice(int price) {
         this.price = price;
     }

    public Book(int price) {
         this.price = price;
     }

    @Override
     public String toString() {
         return super.toString() + "[price=" + price + "]";
     }
}

當爲對象類型賦值時,其實是將兩個對象指向了同一個引用,天然也就很容易修改引用對象的屬性了。blog

public class ObjectDemo {
     public static void main(String[] args) {
         Book book = new Book(10);
         System.out.println("①" + book.toString());
         change(book);
         System.out.println("③" + book.toString());
     }

    private static void change(Book book) {
         book.setPrice(20);
         System.out.println("②change()" + book);
     }
}
運行結果:
①Book@7440e464[price=10]
②change()Book@7440e464[price=20]
③Book@7440e464[price=20]

從運行結果能夠看出:change()方法中的book參數確實和原對象指向了同一地址,也就是說在Java中對象做爲參數傳遞時,其實是把對象在內存中的地址拷貝傳給了參數。這樣一來,對參數對象book的修改也就修改了原對象。

到這裏我就想,兩個對象指向的內存地址是同樣的,那會不會對象做爲參數時,直接傳遞的就是該對象的引用呢?若是這樣的話,咱們修改一下參數book的指向,看看會不會影響原有對象的引用。

public class ObjectDemo2 {
     
public static void main(String[] args) {
     Book b1=new Book(10);
     Book b2=new Book(20);
     System.out.println("before swap" + b1.toString()+b2.toString());
     swap(b1,b2);
     System.out.println("after swap" + b1.toString()+b2.toString());
}

private static void swap(Book pb1, Book pb2) {
     Book temp = pb1;
     pb1 = pb2;
     pb2 = temp;
     System.out.println("swap() pb1 " + pb1);
     System.out.println("swap() pb2 " + pb2);
     pb1.setPrice(100);
     pb2.setPrice(200);
}
}

運行結果:

before swapBook@7440e464[price=10] Book@49476842[price=20]
swap() pb1 Book@49476842[price=20]
swap() pb2 Book@7440e464[price=10]
after swapBook@7440e464[price=200] Book@49476842[price=100]

能夠看到b1和b2引用的對象並無變化,交換的只是拷貝的引用pb1和pb2的地址。

image

3、構造函數


提及構造函數你們一點都不陌生,但有幾點要注意的地方:
1.僅當沒有提供任何構造器的時候,系統纔會默認提供一個無參構造器。
2.構造函數能夠調用另外一個構造函數,可是必須遵照如下幾個規則:
* 構造函數調用必須位於第一行;
* 構造函數只能被調用一次;
* 不能在構造函數之外的任何位置調用構造函數。

public class Person {
     private String name;
     private Integer age;

    public Person(String name) {
         this.name = name;
     }

    public Person(String name, Integer age) {
         this(name);
         this.age = age;
     }

    @Override
     public String toString() {
         return "Person{" +
                 "name='" + name + '\'' +
                 ", age=" + age +
                 '}';
     }

    public static void main(String[] args) {
         Person p = new Person("a", 11);
         System.out.println(p);
     }
}

 

3.初始化順序:先初始化變量,後調用構造函數。
在同一個類中,變量的初始化是和定義的前後順序一致的。不過,即便變量定義在構造函數的後面,仍然會先初始化全部變量,而後才執行構造函數。

public class Order {
     OrderDetail d1 = new OrderDetail(100);
     OrderDetail d2 = new OrderDetail(200);

    public Order() {
         OrderDetail d3 = new OrderDetail(300);
     }

    OrderDetail d4 = new OrderDetail(400);

    public static void main(String[] args) {
         new Order();
     }
}

class OrderDetail {
     public OrderDetail(Integer price) {
         System.out.println("OrderDetail price=" + price);
     }
}

執行結果:

OrderDetail price=100
OrderDetail price=200
OrderDetail price=400
OrderDetail price=300
相關文章
相關標籤/搜索