这篇文章讲解Java代码的基本执行过程

我们先抛开各种JAVA IDE,开发工具,只使用文本编辑器,以突出最本质的东西。

在Linux环境下,我们编辑一个文件:

  1. vim HelloWorld.java

编辑如下代码:

  1. public class HelloWorld{
  2. String name;
  3. public HelloWorld(String name){
  4. this.name = name;
  5. }
  6. public void pHelloWorld(){
  7. System.out.print("HellWorld," + this.name + "\n");
  8. }
  9. public static void main(String []args){
  10. HelloWorld test = new HelloWorld("Lee");
  11. test.pHelloWorld();
  12. }
  13. }

想了解这段代码含义请移步这里

此时这段代码只是一个保存于文件中的字符串,这个文件 HelloWorld.java就称为源程序。

JAVA代码的执行过程如下图(其实很多解释型语言如Python的代码执行机制也类似):

首先在shell中执行:

  1. javac HelloWorld.java

此时将保存着字符串的源程序HelloWorld.java编译成了可由java解释器理解的字节码HelloWorld.class.

下面将该字节码交由解释器运行,执行:

  1. java HelloWorld

结果:

在这里解释一下字节码的概念。

对于C/C++这种语言,编译的时候编译器直接将字符串代码编译成了可交由操作系统直接运行的二进制码.

而对于JAVA,Python这类语言,他们的编译器是先将字符串码翻译成了可交由JAVA/Python解释器运行的字节码,真正运行时是解释器将这些字节码翻译成操作系统认识的二进制码。

下面是对字符串代码,字节码,二进制码的形象体现。

字符串码:

字符串码给人类看。

  1. public class HelloWorld{
  2. String name;
  3. public HelloWorld(String name){
  4. this.name = name;
  5. }
  6. public void pHelloWorld(){
  7. System.out.print("HellWorld," + this.name + "\n");
  8. }
  9. public static void main(String []args){
  10. HelloWorld test = new HelloWorld("Lee");
  11. test.pHelloWorld();
  12. }
  13. }

字节码:

javap -c 可以将java字节码比较形象的显示出来,每一列的第一个数字代表字节码的执行地址编号。

从上往下读就是解释器执行代码的过程。

字节码给java解释器看。

  1. [lijianyang@ workspace]$ javap -c HelloWorld.class
  2. Compiled from "HelloWorld.java"
  3. public class HelloWorld {
  4. java.lang.String name;
  5.  
  6. public HelloWorld(java.lang.String);
  7. Code:
  8. : aload_0
  9. : invokespecial # // Method java/lang/Object."<init>":()V
  10. : aload_0
  11. : aload_1
  12. : putfield # // Field name:Ljava/lang/String;
  13. : return
  14.  
  15. public void pHelloWorld();
  16. Code:
  17. : getstatic # // Field java/lang/System.out:Ljava/io/PrintStream;
  18. : new # // class java/lang/StringBuilder
  19. : dup
  20. : invokespecial # // Method java/lang/StringBuilder."<init>":()V
  21. : ldc # // String HellWorld,
  22. : invokevirtual # // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  23. : aload_0
  24. : getfield # // Field name:Ljava/lang/String;
  25. : invokevirtual # // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  26. : ldc # // String \n
  27. : invokevirtual # // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  28. : invokevirtual # // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
  29. : invokevirtual # // Method java/io/PrintStream.print:(Ljava/lang/String;)V
  30. : return
  31.  
  32. public static void main(java.lang.String[]);
  33. Code:
  34. : new # // class HelloWorld
  35. : dup
  36. : ldc # // String Lee
  37. : invokespecial # // Method "<init>":(Ljava/lang/String;)V
  38. : astore_1
  39. : aload_1
  40. : invokevirtual # // Method pHelloWorld:()V
  41. : return
  42. }

二进制码:

二进制码就是经过解释器解释的字节码,可以直接交由操作系统、CPU执行。

查看Linux的bin目录下的ls文件(对应ls指令的代码)的二进制码:

  1. [lijianyang@ bin]$ hexdump ls | more
  2. 457f 464c
  3. 003e 4b48
  4. c418
  5. 001e 001d
  6.  
  7. 0000
    ...
    ...

上面是二进制码的16进制表示。比如45表示二进制01000101。

附:代码解释

HelloWorld.java

  1. public class HelloWorld{
  2. String name;
  3. public HelloWorld(String name){
  4. this.name = name;
  5. }
  6. public void pHelloWorld(){
  7. System.out.print("HellWorld," + this.name + "\n");
  8. }
  9. public static void main(String []args){
  10. HelloWorld test = new HelloWorld("Lee");
  11. test.pHelloWorld();
  12. }
  13. }

第1行代码建立一个公有类HelloWorld

Java要求每个文件中只能有一个public类,且该公有类的类名必须与文件名一致。

比如这个文件名为HelloWorld.java,那么必须为public class HelloWorld ,其他的都不行 。

如果使用eclipse开发,当你建好一个.java文件时,eclipse会自动为你使用文件名添加公有类的代码。

第2行声明了一个String类型的变量name。

第3-5行定义了类的构造函数。

构造函数是在这个类实例化的时候默认自动调用的函数。构造函数不是必须去定义,如果没有定义,java会调用一个默认的构造函数。

Java定义构造函数就是定义一个与类名同名的方法,且无返回值。

this.name中的this指代这个类实例化后的实例。

比如在第10行我在实例化这个类时将实例取名为test,那么this=test,this.name=test.name.

在这里多说一点,其实一个类中的每一个方法(函数)都有一个默认参数this,比如:

  1. public void test()
    相当于
  2. public void test(this)

这个this是在编译器编译到字节码的时候由编译器自己加上去的,均指代类实例化后那个实例。

第6-8行定义了类的一个方法,叫函数也可以。void表示这个函数的返回类型,没有就是void。

如果一个函数有返回值,那么必须将函数返回类型定义成返回值的类型,如:

  1. public int test(){
  2. return 1
  3. }
  4.  
  5. public String test1(){
  6. return "Hello,World"
  7. }

第9-12行则是定义了一个main函数,main函数是java文件执行的入口。

这个main函数在这个public类中唯一,也在这个文件中唯一。

第10行将类进行实例化。

java使用new关键字将一个类实例化。左侧的HelloWorld表示这个test变量的类型是HelloWorld类,=号右侧将HelloWorld类实例化并赋给test.

第11行调用实例的方法pHelloWorld.Java中的方法调用直接使用符号"."即可,与python一样。

其实python和java有好多相似的地方。或者说各种语言之间都有许多共同点。精通了一门语言,学其他的语言就会事半功倍。

如果上面的描述有误欢迎在评论中指出,因为我也是开始学习不久。

java入门学习笔记之1(类的定义,代码的编译执行)的更多相关文章

  1. Java入门学习笔记(全)

    JAVA https://zhuanlan.zhihu.com/p/21454718 引用部分实验楼代码,侵删 先通读文档 再亲自试标程 复习时自己再批注 1.a = b += c = -~d a = ...

  2. java入门学习(4)— 类,对象理解,如何创建类,对象

    1.什么是类?具有一定相同的属性的对象的集合就叫类.2.对象:类的具体实例,就是类的实例化.比如学生是一个类(student),那学生里面的小红就是一个对象,一个有学生的属性的对象.3.如何定义一个类 ...

  3. java jvm学习笔记七(jar包的代码认证和签名)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 前言: 如果你循序渐进的看到这里,那么说明你的毅力提高了,jvm的很多东西都是比较抽像的,如果不找相对应的代码来辅助理解 ...

  4. Java基础学习笔记十二 类、抽象类、接口作为方法参数和返回值以及常用API

    不同修饰符使用细节 常用来修饰类.方法.变量的修饰符 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权 ...

  5. java入门学习笔记之2(Java中的字符串操作)

    因为对Python很熟悉,看着Java的各种字符串操作就不自觉的代入Python的实现方法上,于是就将Java实现方式与Python实现方式都写下来了. 先说一下总结,Java的字符串类String本 ...

  6. Java入门学习笔记

    Hello.java public class Hello { public static void main(String[] args) { System.out.println("He ...

  7. Android(java)学习笔记118:类继承的注意事项

    /* 继承的注意事项: A:子类只能继承父类所有非私有的成员(成员方法和成员变量) B:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法. C:不要为了部分功能而去 ...

  8. Android(java)学习笔记59:类继承的 注意事项

    1. 类继承的注意事项: /* 继承的注意事项: A:子类只能继承父类所有非私有的成员(成员方法和成员变量) B:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法. ...

  9. Android(java)学习笔记72:线程的状态转换图以及常见执行情况

    1. 线程的状态转换图以及常见执行情况: 2. 线程状态类型: (1)新建状态(New):新创建了一个线程对象.(2)就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start() ...

随机推荐

  1. ASP.Net零碎

    ASP.Net零碎 ServerPush 什么是ServerPush,服务器向客户端浏览器“推送”,其实就是“长连接”. 只有浏览器请求服务器端,服务器端才有给浏览器响应数据,不会主动向浏览器推送数据 ...

  2. HDU 2080 夹角有多大II (数学) atan(y/x)分类求角度

    夹角有多大II Problem Description 这次xhd面临的问题是这样的:在一个平面内有两个点,求两个点分别和原点的连线的夹角的大小.注:夹角的范围[0,180],两个点不会在圆心出现. ...

  3. Spring框架 jar包下载

    Spring框架下载 打开网址https://repo.spring.io 点击左侧边栏第二个按钮 点击 在输入框输入spring-framework点击Search 找到你需要的版本下载就好 教程到 ...

  4. springmvc 方法参数自定义的解析

    1.实现HandlerMethodArgumentResolver接口: 2.在配置文件中添加配置<mvc:argument-resolvers>   <bean class=&qu ...

  5. IOS中常用的UIColor

    UIColor + (UIColor *)blackColor; // 0.0 white 黑色 + (UIColor *)darkGrayColor; // 0.333 white 深灰色 + (U ...

  6. 【python的基本数据类型及进制扫盲】

    一.进制 1.进制简介 进制就是进位制,是人们规定的一种进位方法.计算机底层的数据运算和存储都是二进制数据.计算机语言就是二进制,计算机能直接识别二进制数据,其它数据都不能直接识别. 2.常用进制 对 ...

  7. hdu1151 Air Raid 二分匹配

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1151 求最小路径覆盖 二分图最小路径覆盖=点的个数-最大匹配. 代码: #include<ios ...

  8. 转:Linux中文显示乱码?如何设置centos显示中文

    怎么设置Linux系统中文语言,这是很多小伙伴在开始使用Linux的时候,都会遇到一个问题,就是终端输入命令回显的时候中文显示乱码.出现这个情况一般是由于没有安装中文语言包,或者设置的默认语言有问题导 ...

  9. 1.centOS安装Mysql

    上个星期研究了一个星期的Mysql,从今天起把学到的东西整理一下. ---------------------------------------------- mysql安装本人亲试过两种安装方式, ...

  10. ucenter 单点登录,终极版

      一 ,discuz ecshop  两边登陆都可以同步登陆到另一程序上,但退出则无法实现同步登陆.顺着 Ecshop 的退出流程,顺藤摸瓜找到了 lib_common.php 文件中的 uc_ca ...