java入门学习笔记之1(类的定义,代码的编译执行)

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

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

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

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中执行:

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解释器看。

[[email protected]192 workspace]$ javap -c HelloWorld.class
Compiled from "HelloWorld.java"
public class HelloWorld {
  java.lang.String name;

  public HelloWorld(java.lang.String);
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: aload_1
       6: putfield      #2                  // Field name:Ljava/lang/String;
       9: return

  public void pHelloWorld();
    Code:
       0: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: new           #4                  // class java/lang/StringBuilder
       6: dup
       7: invokespecial #5                  // Method java/lang/StringBuilder."<init>":()V
      10: ldc           #6                  // String HellWorld,
      12: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      15: aload_0
      16: getfield      #2                  // Field name:Ljava/lang/String;
      19: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      22: ldc           #8                  // String \n
      24: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      27: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      30: invokevirtual #10                 // Method java/io/PrintStream.print:(Ljava/lang/String;)V
      33: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #11                 // class HelloWorld
       3: dup
       4: ldc           #12                 // String Lee
       6: invokespecial #13                 // Method "<init>":(Ljava/lang/String;)V
       9: astore_1
      10: aload_1
      11: invokevirtual #14                 // Method pHelloWorld:()V
      14: return
}

二进制码:

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

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

[[email protected]192 bin]$ hexdump ls | more
0000000 457f 464c 0102 0001 0000 0000 0000 0000
0000010 0002 003e 0001 0000 4b48 0040 0000 0000
0000020 0040 0000 0000 0000 c418 0001 0000 0000
0000030 0000 0000 0040 0038 0009 0040 001e 001d
0000040 0006 0000 0005 0000 0040 0000 0000 0000
0000050 0040 0040 0000 0000 0040 0040 0000 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,比如:

public void test() 相当于
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有好多相似的地方。或者说各种语言之间都有许多共同点。精通了一门语言,学其他的语言就会事半功倍。

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

时间: 2024-10-11 23:41:26

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

PHP入门学习笔记之—— PHP 类与对象 (下)

N.魔术方法 :__construct, __destruct (参看 构造方法和析构方法), __call, __callStatic, __get, __set, __isset, __unset (参看 重载), __sleep, __wakeup, __toString, __set_state 和 __clone 等方法在PHP中被称为"魔术方法"(Magic methods). 在命名自己的类方法时不能使用这些方法名. Caution PHP把所有以__(两个下划线)开头的

Python学习笔记2:类的定义和继承

# 类的定义 格式: class 类名(父类): __init(self,参数) 成员方法 成员变量 # 所有类的基础object #  私有方法和变量使用__开头 例如:定义一个鸟类 class Bird(object): __have_feather = True # 私有属性:是否有羽毛 way_of_reproduct = "egg" # 公有属性:繁殖方式 def move(self, dx, dy): # 公有方法 position = [0,0] position[0]

Java入门学习笔记(0)——认识变量

HelloWorld 1 //HelloWorld.java 2 3 public class HelloWorld { 4 public static void main (String[] args) { 5 System.out.println("Hello,World!"); 6 } 7 } 基础不牢,地动山摇.学习还是从“HelloWorld”开始吧! 第一个程序:1.编写并保存源代码<HelloWorld.java> 2.编译<javac  HelloWo

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

不同修饰符使用细节 常用来修饰类.方法.变量的修饰符 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权限修饰符,默认访问, 类,方法,成员变量 private 权限修饰符,私有访问, 方法,成员变量 static 静态修饰符 方法,成员变量 final 最终修饰符 类,方法,成员变量,局部变量 abstract 抽象修饰符 类 ,方法 我们编写程序时,权限修饰符一般放于所有修饰符之前,不同的权限修饰

黑马程序员--Java基础学习笔记【Object类、String类】

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- Object类 在Java类继承结构中,java.lang.Object类位于顶端. 所有类都直接或间接继承Object类. (接口不能继承Object类,接口中隐含定义了Object类的所有公共方法,但是全抽象) Object类型的引用变量可以指向任何类型对象. Object类成员方法 public String toString() { return getClass().getName(

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

因为对Python很熟悉,看着Java的各种字符串操作就不自觉的代入Python的实现方法上,于是就将Java实现方式与Python实现方式都写下来了. 先说一下总结,Java的字符串类String本身定义了一些简单的字符串操作, 字符串常用操作有: 1. 取某一字符第一次出现/最后一次出现的索引 2. 取字符串某一位置的字符 3. 字符串截取 4. 去除首尾空格 5. 字符串字符替换 6. 判断两个字符串是否相等 7. 大小写转换 下面开始: 1.取某一字符第一次出现/最后一次出现的索引 JA

Java IO学习笔记:File类

File类 在整个IO包了,唯一表示与文件本身有关的类就是File类.使用File类可以进行1创建或删除文件等常用操作.要想使用File类.则首先要观察File类的构造方法,此类的      常用构造方法如下所示:public File(String pathname) 实例化File类的时候,必须设置好路径 No. 方法或常量 类型 描述 1 public static final String pathSeparator 常量 表示路径的分隔符(windows是“;”) 2 public s

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

1 /* 2 继承的注意事项: 3 A:子类只能继承父类所有非私有的成员(成员方法和成员变量) 4 B:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法. 5 C:不要为了部分功能而去继承 6 class A { 7 public void show1(){} 8 public void show2(){} 9 } 10 11 class B { 12 public void show2(){} 13 public void show3(){} 14 } 15

Android(java)学习笔记128:使用proguard混淆android代码

1.当前是有些工具比如apktool,dextojar等是可以对我们android安装包进行反编译,获得源码的.为了减少被别人破解,导致源码泄露,程序被别人盗取代码,等等.我们需要对代码进行混淆,android的sdk中为我们提供了ProGuard这个工具,可以对代码进行混淆(一般是用无意义的名字来重命名),以及去除没有使用到的代码,对程序进行优化和压缩,这样可以增加你想的难度.最近我做的项目,是我去配置的混淆配置,因此研究了一下,这里分享一下. 2.上面说到去除没有使用到的代码,对程序进行优化