本文章记录《Head Firs Java》的学习过程中的知识点,并根据自己的理解加以描述,在某些地方会加入相应的代码进行解释。如果有错误的地方,请加以指正。
这个不在本书的讲述范围之内,安装教程在这里可以找到。
我们编写的以xxx.java为后缀形式的源文件,经过一个叫做javac的编译器(Java Compiler)编译
$javac xxx.java
输出一个带xxx.class后缀的与平台无关的字节码,也就是类文件。最后面通过Java虚拟机(JVM 即Java Virtual Machine)执行字节码。
$java xxx
注意:在执行类文件的时候,只需要类文件名,不需要.class的后缀文件名。
至于Java代码的编译原理即编译器和JVM是怎么工作的,可以看看这篇文章先做了解。具体的我也是不太懂啊。。
这张图已经详细的给出了Java的程序结构。主要是三句话:
类存于源文件里面
方法存于类中
语句存于方法中
这里需要注意的是,类名必须与源文件名一致。
比如说我创建一个HelloWorld.java的源文件,里面的代码如下:
public class HelloWorld{
public static void main(String[] args)
{
System.out.println("HelloWorld");
}
}
$javac HelloWorld.java
$java
是可以编译执行的。
但是我如果将HelloWorld.java的名字改成helloworld.java时,编译就会提示如下错误:
也因此,同一个java源文件中不能同时存在两个及以上的类。
这里我所理解的方法相当于C/C++中的函数。
在文中有这么一句话:
方法必须在类的内部中声明
因为在C/C++有函数的声明和定义区分。在C++中,可以在.h文件中声明类以及类的方法,然后在.cpp文件中定义方法的具体实现。那么Java可以在类中的内部声明方法,在外部定义呢?我有尝试过写如下代码:
public class HelloWorld{
public static void main(String[] args)
{
System.out.println("HelloWorld");
}
public void PrintHelloJava()
{
System.out.println("HelloJava");
}
public void PrintHelloCpp();
}
void HelloWorld::PrintHelloCpp()
{
System.out.println("HelloCpp");
}
上述代码编译不通过,错误提示如下:
网上copy了这么一段,只能等接下来学习了抽象类才知道了:
在Java里如果出现这种情况,那么方法的声明类必须是一个父类或者接口。
声明的方法必须被abstract修饰,也就是抽象方法。
方法的实现类必须是继承了这个父类的子类,或实现了这个接口的实现类。
在写上述测试代码的过程中发现这么一个问题:
public class HelloWorld{
public void PrintHelloJava()
{
System.out.println("HelloJava");
}
public static void main(String[] args)
{
System.out.println("HelloWorld");
PrintHelloJava(); // 直接调用PrintHelloJava方法
}
}
在C/C++中,如果函数定义在函数调用的前面,这样的函数调用是没问题的。于是乎我就想在Java中试一试。PrintHelloJava()在main()之前定义,我就觉得在main()中调用PrintHelloJava()是没问题的。但是,编译的时候提示错误了:
无法从静态上下文中引用非静态方法
这句话具体是什么意思表示不明白,那么能够从静态上下文中调用静态方法吗?我就把
public void PrintHelloJava()
改为
public static void PrintHelloJava()
竟然可以编译运行。网上搜索那个错误的解释,如下说明:
因为我们知道静态的方法可以在没有创建实例时使用,而申明为非静态的成员变量是一个对象属性,它只有在对象存在时引用,因此如果在对象未创建实例时我们在静态方法中调用了非静态成员方法自然是非法的,所以编译器会在这种时候给各错误.
简单说来,静态方法可以不用创建对象就调用,非静态方法必须有了对象的实例才能调用.因此想在静态方法中引用非静态方法是不可能的,因为它究竟引用的是哪个对象的非静态方法呢?编译器不可能给出答案,因为没有对象啊,所以要报错
这篇文章对于Java中的静态变量和静态方法有详细的描述。
根据上面的描述,我们就很清楚为什么main()要声明为static方法了。因为main()是一个入口函数,只有声明为静态方法,因为这个方法要在实例化之前就运行了
除了将PrintHelloJava()声明为静态方法外,可以通过HelloWorld类的对象的实例化来进行调用,如下:
public class HelloWorld{
public void PrintHelloJava()
{
System.out.println("HelloJava");
}
public static void main(String[] args)
{
HelloWorld myhelloworld = new HelloWorld();
System.out.println("HelloWorld");
myhelloworld.PrintHelloJava();
}
}
上述代码编译运行都是OK的。