1. 程式人生 > >[java]初學者java編譯時錯誤小總結

[java]初學者java編譯時錯誤小總結

初學者常遇Java編譯時錯誤

編譯錯誤 ErrorMessage
錯誤: 非法的型別開始 illegal start of type
錯誤: 需要’;’ ‘;’ expected
錯誤: 方法宣告無效;需要返回型別 invalid method declaration; return type required
錯誤: 需要<識別符號> < identifier> expected
錯誤: 無法從靜態上下文中引用非靜態 變數 error: non-static variable s cannot be referenced from a static context
錯誤: 無法從靜態上下文中引用非靜態 方法 error: non-static method Print(String) cannot be referenced from a static context

程式碼舉例

程式碼嘗試1.0

原始碼1.0

這是我根據本文契機程式碼寫的錯誤情況簡化程式碼,我的初衷是希望這個程式碼執行的時候,輸出一個“Hello,world”,但是很不幸地我把列印字串的命令寫在了類中但是任何一個方法外面。

public class Nothing
{
    private String s = "Hello,World!";
    this
.Print(s); // <- ERROR private void Print(String s){ System.out.println(s); } }

編譯1.0

一口氣報了四個錯誤!

>javac Nothing.java
Nothing.java:4: 錯誤: 非法的型別開始
        this.Print(s);
        ^
Nothing.java:4: 錯誤: 需要';'
        this.Print(s);
            ^
Nothing.java:4: 錯誤: 方法宣告無效; 需要返回型別
this.Print(s); ^ Nothing.java:4: 錯誤: 需要<識別符號> this.Print(s); ^ 4 個錯誤 >javac -J-Duser.language=en Nothing.java //[1] Nothing.java:4: error: illegal start of type this.Print(s); ^ Nothing.java:4: error: ';' expected this.Print(s); ^ Nothing.java:4: error: invalid method declaration; return type required this.Print(s); ^ Nothing.java:4: error: <identifier> expected this.Print(s); ^ 4 errors

程式碼嘗試1.1

原始碼1.1

然後,我想起來了,有建構函式這麼一回事,應該把方法解除安裝建構函式裡面,放進去啦,在再main裡面啟動這個方法,哦吼吼!

public class Nothing
{
    private String s = "Hello,World!";
    private void Print(String s){
        System.out.println(s);
    }
    public Nothing(){
        Print(s);
    }
    public static void main(String args[])
    {
        Nothing(); // <- ERROR
    }
}

編譯1.1

失敗了,居然說找不到符號,這是你自己的建構函式啊,你怎麼找不到啊!


>javac Nothing.java
Nothing.java:12: 錯誤: 找不到符號
                Nothing();
                ^
  符號:   方法 Nothing()
  位置: 類 Nothing
1 個錯誤

>javac -J-Duser.language=en  Nothing.java
Nothing.java:12: error: cannot find symbol
                Nothing();
                ^
  symbol:   method Nothing()
  location: class Nothing
1 error

程式碼嘗試1.2

原始碼1.2

然後,我想起來任何建構函式要啟動它好像一定要有一個物件…

public class Nothing
{
    private String s = "Hello,World!";
    private void Print(String s){
        System.out.println(s);
    }
    public Nothing(){
        Print(s);
    }
    public static void main(String args[])
    {
        Nothing n = new Nothing(); // main裡面宣告一個物件,自動觸發建構函式
    }
}

編譯1.2

總算有一個通過編譯,執行成功的版本了!


>javac -J-Duser.language=en  Nothing.java

>java Nothing
Hello,World!

程式碼嘗試1.3

原始碼1.3

反正,都寫到這個份上了,那就連print()也直接來一次吧,看看編譯錯誤資訊是不是一樣:

public class Nothing
{
    private String s = "Hello,World!";
    private void Print(String s){
        System.out.println(s);
    }
    public static void main(String args[]){
        Print(s); // <-ERROR
    }
}

編譯

什麼?你更在乎它是不是靜態的?什麼,你連自己的建構函式都找不到卻能找到print了?還是說不是靜態更嚴重,print找不到找得到都無所謂了?

>javac Nothing.java
Nothing.java:9: 錯誤: 無法從靜態上下文中引用非靜態 變數 s
                Print(s);
                      ^
Nothing.java:9: 錯誤: 無法從靜態上下文中引用非靜態 方法 Print(String)
                Print(s);
                ^
2 個錯誤

>javac -J-Duser.language=en  Nothing.java
Nothing.java:8: error: non-static variable s cannot be referenced from a static
context
                Print(s);
                      ^
Nothing.java:8: error: non-static method Print(String) cannot be referenced from
 a static context
                Print(s);
                ^
2 errors

程式碼嘗試1.4

原始碼1.4

好吧,我懂了,還是老老老實實地寫符合規則的程式碼吧,

public class Nothing
{
    private String s;
    private static  void Print(String s){ // 看,我給你加static了。
        System.out.println(s);
    }
    public static void main(String args[]){
        s = "Hello,World"; // 我拿到這裡來賦值就沒問題了吧!
        Print(s);
    }
}

編譯1.4

真是實力不會寫Java….


>javac Nothing.java
Nothing.java:10: 錯誤: 無法從靜態上下文中引用非靜態 變數 s
                s = "Hello,World";
                ^
Nothing.java:11: 錯誤: 無法從靜態上下文中引用非靜態 變數 s
                Print(s);
                      ^
2 個錯誤
>javac -J-Duser.language=en  Nothing.java
Nothing.java:8: error: non-static variable s cannot be referenced from a static
context
                s = "Hello,World";
                ^
Nothing.java:9: error: non-static variable s cannot be referenced from a static
context
                Print(s);
                      ^
2 errors

程式碼嘗試1.5

原始碼1.5

所以,不用建構函式的就這樣寫….


public class Nothing
{
    private static  void Print(String s){
        System.out.println(s);
    }
    public static void main(String args[]){
        String s = "Hello,World";
        Print(s);
    }
}

編譯1.5

H E L O , W O R L D


>javac -J-Duser.language=en  Nothing.java

>java Nothing
Hello,World

本文契機

出錯程式碼

/* 不完整原始碼:實現一個 FIFO Queue 佇列類的迭代器程式碼 */

import java.util.Iterator;//[3]迭代器
class Queue<Item>
{
    //...
    private Node first;
    private class Node
    {
        Item item;
        Node next;
    }
    // 假定這個可以反轉連結串列結構並返回一個新的起點
    private Node reverse(Node current){
    }
    /************************* 迭代器實現 ******************************/
    public Iterator<Item> iterator(){
        return new ListIterator();
    }
    // 類中類
    private class ListIterator implements Iterator<Item>//[3]迭代器
    {
        private Node current;

        current = reverse(first); // <-ERROR 這句程式碼就這麼生生地被我寫在了這裡 見1.1

        public boolean hasNext(){}
        public Item next(){}
        public void remove(){}
    }
    // ... 
    /************************* 迭代器實現 ******************************/

}

建構函式

public Iterator<Item> iterator(){
        return new ListIterator();
    }
    private class ListIterator implements Iterator<Item>//[3]迭代器
    {
        private Node current;

        public  ListIterator()
        {
            current = reverse(first); // YES!
        }

        public boolean hasNext(){}
        public Item next(){}
        public void remove(){}
    }

程式碼心得

這種問題屬於Java的程式設計規範和語法規定吧,但是編譯的時候給的提示資訊也讓人很困惑,寫著寫著就寫懵了,其實我也認可這個世界上沒有Stupid Code,但是底線是程式碼好歹要通過編譯啊!一定要讓自己記住這個深刻的教訓。人啊,比起作對,更難是找到自己的錯、改正自己的錯啊!

參考引用