1. 程式人生 > >java main方法呼叫類的例項化方法疑問

java main方法呼叫類的例項化方法疑問

public class Example {
     void idea() {
     }
     public static void main(String args[]) {
         new Example().idea();//這裡居然不報錯. main方法是個靜態方法,java中不是明文規定在靜態方法中不能呼叫非靜態方法嗎?
     }
 }

簡而言之:
首先,static中可以建立例項,但不能訪問本類的某個已有例項(除非傳遞進來的)
其次靜態方法是不能呼叫非靜態方法和屬性,前提是不能呼叫沒有確定例項化物件的非靜態方法和屬性,而new Example()並不是一個單純的非靜態方法,它是在構建一個類物件及其初始化物件,返回的是一個物件例項,相當於呼叫的是一個以構建好的例項化物件。物件都確定了,非靜態方法當然可以使用了(靜態方法和靜態屬性是類中所有物件所共有的!所以是類直接呼叫的)。

這裡要說到new關鍵字,它的作用是呼叫類的建構函式建立物件,返回該物件在記憶體中的引用(地址)

這裡有個問題,我們知道在使用new關鍵字時是呼叫類的建構函式來例項化物件,但是我們往往可以看到在建構函式中使用this的情況,這是怎麼回事?此時不是沒有例項化物件嗎?其他非靜態成員方法不都是在呼叫構造方法後才呼叫執行的嗎?

類的構造方法中可以呼叫非靜態成員變數/方法,可以使用this關鍵字

 public class ThisDemo {
    String name;
    int age;
    public ThisDemo (){ 
        this.age=21;
   }     
    public
ThisDemo(String name,int age){ this(); this.name="Mick"; } private void print(){ System.out.println("最終名字="+this.name); System.out.println("最終的年齡="+this.age); } public static void main(String[] args) { ThisDemo tt=new ThisDemo("",0); //隨便傳進去的引數
tt.print(); } }

其實:java物件建立其實是在建構函式開始執行之前,就是說建構函式執行的時候,被構造的物件其實已經存在了,所以建構函式中可以用this引用當前被構造的物件進行處理(這裡其實相當於一個賦值初始化的過程,將記憶體堆中的例項引用傳遞給this,從而this指向當前例項化物件,一切就都順理成章了)。

在【 java程式設計思想】裡關於一個類的初始化順序的解釋。

在這裡有必要總結一下物件的建立過程。請考慮一個名為Dog 的類:

(1) 型別為Dog 的一個物件首次建立時,或者Dog 類的static 方法/static 欄位首次訪問時,Java 直譯器必須找到Dog.class(在事先設好的類路徑裡搜尋)。

(2) 找到Dog.class 後(它會建立一個Class 物件,這將在後面學到),它的所有static 初始化模組都會執行。因此,static 初始化僅發生一次——在Class 物件首次載入的時候。

(3) 建立一個new Dog()時,Dog 物件的構建程序首先會在記憶體堆(Heap)裡為一個Dog 物件分配足夠多的儲存空間。

(4) 這種儲存空間會清為零(這裡的意思是對基本型別賦初值,初始化的意思),將Dog 中的所有基本型別設為它們的預設值(零用於數字,以及boolean和char 的等價設定)。

(5) 進行欄位定義時發生的所有初始化都會執行。

(6) 執行構建器。

從上面類的初始化順序可以看出當程式中呼叫了類的建構函式時記憶體堆中已經存在當前類的一個例項化物件,這也是為什麼能在建構函式中使用this來呼叫非靜態變數/方法的原因。

相關推薦

Java:main()函式呼叫方法的限制

1、在本類中呼叫自己的方法,方法必須為靜態的,否則報錯; 通過遞迴方法,實現N!的演算法。   public class TestRecursion { public static void main(String[] args) { System.out.print

java利用反射呼叫的某個方法

程式碼如下: 列印類Print.java package com.test.reflct; /** * 列印類 * * @date 2015-8-12 下午2:18:42 */ public class Print { public static

JAVA中關於String例項時記憶體的問題

String類在JAVA開發中是必不可少的 但是  String物件在例項化時記憶體問題卻很嚴重 String類以下有兩種例項化方式 ⑴用 new String ( ) 如  String str = new String("Hello World!")  系統會先為括號裡

java main方法呼叫例項方法疑問

public class Example { void idea() { } public static void main(String args[]) { new Example().idea();//這裡居然

Java中可以直接呼叫中靜態方法,不用例項

轉載自   http://stevengw.blog.163.com/blog/static/583447512012319112140126/ 先通俗的分析下,我們把類看作是一個房子。房子裡面有傢俱,桌椅板凳之類的,房子裡面還有人。 房子裡面所有的人都應該是共有一套傢俱

python中子例項呼叫方法

面向物件的核心為物件,物件是由類例項化而來的,那麼類與類之間存在一個繼承的關係,被繼承的類叫做父類,繼承了父類的類為子類。 子類繼承了父類,那麼子類例項化的物件就可以呼叫所有父類的方法,當然也可以呼叫子類自身所有的方法。因為這些方法都屬於該物件的方法。 比如,子類child

Python內建函式方法靜態方法例項方法學習

靜態方法 class C(object): @staticmethod def f(): print('runoob'); C.f(); # 靜態方法無需例項化 cobj = C() cobj.f() # 也可以例項化後

java 如何使用多執行緒呼叫的靜態方法

  1.情景展示   靜態方法內部實現:將指定內容生成圖片格式的二維碼;   如何通過多執行緒實現? 2.分析   之所以採用多執行緒,是為了節省時間  3.解決方案   準備工作   logo檔案     將生成的檔案儲存在F

iOS 一個只允許外部呼叫特定初始方法來初始

問題:一個類只想讓外部呼叫特定初始化方法來初始化 例如只允許呼叫 - (instancetype)initWithName:(NSString *)name; NS_UNAVAILABLE :標記方

java利用反射獲取某個包下的所有獲取物件屬性、方法、並例項

首先貼上用到的jar包,當然也可以通過遞迴file.list獲取類的路徑名稱。 maven匯入jar包: <dependency> <groupId>

Java反射練習三:呼叫的private方法以及屬性

package com.fu.demo;import java.lang.reflect.Field;import java.lang.reflect.Method;/** * 通過反射呼叫類的private方法以及屬性 * */public class ReflectByI

Java反射高階應用--利用反射呼叫的私有方法修改私有方法值,以及替換Java成員資料

  package me.test; import java.lang.reflect.*;  //匯入反射需要的包 public class ReflectTest {  public static void main(String[] args)  throws  Ex

利用wsdl地址生成java客戶端呼叫並實現動態配置的方法

前言:        有時,我們經常要和一些外部系統對接,如果是HTTP介面還好,直接用apache的HttpClient工具類呼叫即可。而如果對方系統是Webservice,則比較麻煩,本文主要講解如何用對方的wsdl地址生成java客戶端呼叫類並且動態配置訪問地址並在ja

反射動態呼叫例項窗體的方法

/// <summary> /// 開啟新的子窗體 /// </summary> /// <param name="strName">窗體的類名</param>

Javamain函式呼叫同類中的方法

1、需要建立這個類的例項,再進行呼叫 public class Test{ public static void main(String[] args){ Test t = new Test(); t.train(); }   voidtrain(){ System.out.println("china")

Java中常用的及常用方法的一些例項

package shiyan6; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; public class Test6  {      public static

Python的方法、靜態方法例項方法

#-*- coding:utf-8 -*- class A: def __init__(self,name): self.name=name @staticmethod def staticfun(): p

JAVA基礎篇—抽象,抽象方法

java b- rec package rate idt -c over stub class Shape 1 package com.shape; 2 3 public abstract class Shape { 4 double area;//

JAVA基礎 String包裝下 .replace方法的使用以及char和字符序列的使用場景

clas 打開 set 如果 ava lac pla 反轉 XML ptLink0.setText(arbu.getPtLink().replace("&","&amp;")); // 如果像 ‘&

java中的抽象和抽象方法

抽象方法:在類中沒有方法體的方法,就是抽象方法。 抽象類:含有抽象方法的類就叫抽象類。 抽象類中的抽象方法必須被實現!如果一個子類沒有實現父類中的抽象方法,則子類也成為了一個抽象類!抽象類中的普通方法,可以不必實現。 1 用abstract關鍵字來修飾一個類時,這個類叫做抽象類;用abstr