java入门学习笔记之1(类的定义,代码的编译执行)
这篇文章讲解Java代码的基本执行过程
我们先抛开各种JAVA IDE,开发工具,只使用文本编辑器,以突出最本质的东西。
在Linux环境下,我们编辑一个文件:
vim HelloWorld.java
编辑如下代码:
public class HelloWorld{
String name;
public HelloWorld(String name){
this.name = name;
}
public void pHelloWorld(){
System.out.print("HellWorld," + this.name + "\n");
}
public static void main(String []args){
HelloWorld test = new HelloWorld("Lee");
test.pHelloWorld();
}
}
想了解这段代码含义请移步这里。
此时这段代码只是一个保存于文件中的字符串,这个文件 HelloWorld.java就称为源程序。
JAVA代码的执行过程如下图(其实很多解释型语言如Python的代码执行机制也类似):
首先在shell中执行:
javac HelloWorld.java
此时将保存着字符串的源程序HelloWorld.java编译成了可由java解释器理解的字节码HelloWorld.class.
下面将该字节码交由解释器运行,执行:
java HelloWorld
结果:
在这里解释一下字节码的概念。
对于C/C++这种语言,编译的时候编译器直接将字符串代码编译成了可交由操作系统直接运行的二进制码.
而对于JAVA,Python这类语言,他们的编译器是先将字符串码翻译成了可交由JAVA/Python解释器运行的字节码,真正运行时是解释器将这些字节码翻译成操作系统认识的二进制码。
下面是对字符串代码,字节码,二进制码的形象体现。
字符串码:
字符串码给人类看。
public class HelloWorld{
String name;
public HelloWorld(String name){
this.name = name;
}
public void pHelloWorld(){
System.out.print("HellWorld," + this.name + "\n");
}
public static void main(String []args){
HelloWorld test = new HelloWorld("Lee");
test.pHelloWorld();
}
}
字节码:
javap -c 可以将java字节码比较形象的显示出来,每一列的第一个数字代表字节码的执行地址编号。
从上往下读就是解释器执行代码的过程。
字节码给java解释器看。
[lijianyang@ workspace]$ javap -c HelloWorld.class
Compiled from "HelloWorld.java"
public class HelloWorld {
java.lang.String name; public HelloWorld(java.lang.String);
Code:
: aload_0
: invokespecial # // Method java/lang/Object."<init>":()V
: aload_0
: aload_1
: putfield # // Field name:Ljava/lang/String;
: return public void pHelloWorld();
Code:
: getstatic # // Field java/lang/System.out:Ljava/io/PrintStream;
: new # // class java/lang/StringBuilder
: dup
: invokespecial # // Method java/lang/StringBuilder."<init>":()V
: ldc # // String HellWorld,
: invokevirtual # // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
: aload_0
: getfield # // Field name:Ljava/lang/String;
: invokevirtual # // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
: ldc # // String \n
: invokevirtual # // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
: invokevirtual # // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
: invokevirtual # // Method java/io/PrintStream.print:(Ljava/lang/String;)V
: return public static void main(java.lang.String[]);
Code:
: new # // class HelloWorld
: dup
: ldc # // String Lee
: invokespecial # // Method "<init>":(Ljava/lang/String;)V
: astore_1
: aload_1
: invokevirtual # // Method pHelloWorld:()V
: return
}
二进制码:
二进制码就是经过解释器解释的字节码,可以直接交由操作系统、CPU执行。
查看Linux的bin目录下的ls文件(对应ls指令的代码)的二进制码:
[lijianyang@ bin]$ hexdump ls | more
457f 464c
003e 4b48
c418
001e 001d 0000
...
...
上面是二进制码的16进制表示。比如45表示二进制01000101。
附:代码解释
HelloWorld.java
public class HelloWorld{
String name;
public HelloWorld(String name){
this.name = name;
}
public void pHelloWorld(){
System.out.print("HellWorld," + this.name + "\n");
}
public static void main(String []args){
HelloWorld test = new HelloWorld("Lee");
test.pHelloWorld();
}
}
第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,比如:
public void test()
相当于
public void test(this)
这个this是在编译器编译到字节码的时候由编译器自己加上去的,均指代类实例化后那个实例。
第6-8行定义了类的一个方法,叫函数也可以。void表示这个函数的返回类型,没有就是void。
如果一个函数有返回值,那么必须将函数返回类型定义成返回值的类型,如:
public int test(){
return 1
} public String test1(){
return "Hello,World"
}
第9-12行则是定义了一个main函数,main函数是java文件执行的入口。
这个main函数在这个public类中唯一,也在这个文件中唯一。
第10行将类进行实例化。
java使用new关键字将一个类实例化。左侧的HelloWorld表示这个test变量的类型是HelloWorld类,=号右侧将HelloWorld类实例化并赋给test.
第11行调用实例的方法pHelloWorld.Java中的方法调用直接使用符号"."即可,与python一样。
其实python和java有好多相似的地方。或者说各种语言之间都有许多共同点。精通了一门语言,学其他的语言就会事半功倍。
如果上面的描述有误欢迎在评论中指出,因为我也是开始学习不久。
java入门学习笔记之1(类的定义,代码的编译执行)的更多相关文章
- Java入门学习笔记(全)
JAVA https://zhuanlan.zhihu.com/p/21454718 引用部分实验楼代码,侵删 先通读文档 再亲自试标程 复习时自己再批注 1.a = b += c = -~d a = ...
- java入门学习(4)— 类,对象理解,如何创建类,对象
1.什么是类?具有一定相同的属性的对象的集合就叫类.2.对象:类的具体实例,就是类的实例化.比如学生是一个类(student),那学生里面的小红就是一个对象,一个有学生的属性的对象.3.如何定义一个类 ...
- java jvm学习笔记七(jar包的代码认证和签名)
欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 前言: 如果你循序渐进的看到这里,那么说明你的毅力提高了,jvm的很多东西都是比较抽像的,如果不找相对应的代码来辅助理解 ...
- Java基础学习笔记十二 类、抽象类、接口作为方法参数和返回值以及常用API
不同修饰符使用细节 常用来修饰类.方法.变量的修饰符 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权 ...
- java入门学习笔记之2(Java中的字符串操作)
因为对Python很熟悉,看着Java的各种字符串操作就不自觉的代入Python的实现方法上,于是就将Java实现方式与Python实现方式都写下来了. 先说一下总结,Java的字符串类String本 ...
- Java入门学习笔记
Hello.java public class Hello { public static void main(String[] args) { System.out.println("He ...
- Android(java)学习笔记118:类继承的注意事项
/* 继承的注意事项: A:子类只能继承父类所有非私有的成员(成员方法和成员变量) B:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法. C:不要为了部分功能而去 ...
- Android(java)学习笔记59:类继承的 注意事项
1. 类继承的注意事项: /* 继承的注意事项: A:子类只能继承父类所有非私有的成员(成员方法和成员变量) B:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法. ...
- Android(java)学习笔记72:线程的状态转换图以及常见执行情况
1. 线程的状态转换图以及常见执行情况: 2. 线程状态类型: (1)新建状态(New):新创建了一个线程对象.(2)就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start() ...
随机推荐
- UBIFS文件系统介绍
1. 引言 UBIFS,Unsorted Block Image File System,无排序区块图像文件系统.它是用于固态硬盘存储设备上,并与LogFS相互竞争,作为JFFS2的后继文件系统之一 ...
- jQuery修炼心得-DOM节点的删除
要移除页面上节点是开发者常见的操作,jQuery提供了几种不同的方法用来处理这个问题. 1.empty empty 顾名思义,清空方法,但是与删除又有点不一样,因为它只移除了 指定元素中的所有子节点. ...
- mui开发app之多图压缩与上传(仿qq空间说说发表)
欲实现效果图 提出需求点: 用户可自由添加删除替换多张图片,并且显示相应缩略图,限制为8张 用户可选择压缩图或直接上传原图功能 返回提醒用户会丢失填写的信息 下面一个个实现上述需求,从简单到复杂: 需 ...
- 基于Activiti的流程应用开发平台JSAAS-WF V5.3
第1章 产品概述及体系架构 1.1.概述 红迅JSAAS-WF工作流平台V5是广州红迅软件有限公司面向合作伙伴以及有IT运维团队中大型企业提供新一代的流程管理产品,它基于流行的JAVA开源技术上构建, ...
- C#集合之字典
字典表示一种复杂的数据结构,这种数据结构允许按照某个键来访问元素.字典也称为映射或散列表. 字典的主要特性是能根据键快速查找值.也可以自由添加和删除元素,这有点像List<T>(http: ...
- linux上安装tcl
1. 首先下载安装包,推荐下载activetcl(对tcl源码进行了预编译,安装步骤简单).打开网址http://activestate.com找到activetcl的社区版(社区版是免费的,找到li ...
- [刷题]算法竞赛入门经典(第2版) 6-7/UVa804 - Petri Net Simulation
题意:模拟Petri网的执行.虽然没听说过Petri网,但是题目描述的很清晰. 代码:(Accepted,0.210s) //UVa804 - Petri Net Simulation //Accep ...
- 如何实现在Windows上运行Linux程序,附示例代码
微软在去年发布了Bash On Windows, 这项技术允许在Windows上运行Linux程序, 我相信已经有很多文章解释过Bash On Windows的原理, 而今天的这篇文章将会讲解如何自己 ...
- angular4 JavaScript内存溢出问题 (FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory)
最近在写基于angular4的项目的时候,在build --prod的时候,突然措手不及的蹦出个报错,大致错误如下: 70% building modules 1345/1345 modules 0 ...
- 通过vmware 启动cloudera-quickstart-vm-5.10.0-0-vmware.zip镜像无法启动。
解压cloudera-quickstart-vm-5.10.0-0-vmware.zip中找到cloudera-quickstart-vm-5.10.0-0-vmware.vmx文件打开注释点#msg ...