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

     2022-03-19     301

关键词:

这篇文章讲解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有好多相似的地方。或者说各种语言之间都有许多共同点。精通了一门语言,学其他的语言就会事半功倍。

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

 





java学习注解和反射超详细笔记(代码片段)

目录一、注解1、注解入门2、内置注解3、自定义注解,元注解二、反射机制1、Java反射机制概念1.1静态&动态语言1.2反射机制概念1.3反射机制研究与应用1.4反射机制优缺点1.5实现2、理解Class类并获取Class实例2.1class类介绍2.2获取Cla... 查看详情

egret入门学习笔记之问题解决

一、super()的用处MaskLayer继承了eui.Component,constructor是类的入口super()代表执行父类的构造函数二、人物动画我设计的效果是:人物随着手指触摸屏幕任何一点而走动。但是当我使用varboy2=egret.Tween.get(mc2);boy2.to(x:e.stageX,y:e.stageY,2000);... 查看详情

机器学习编译入门课程学习笔记第一讲机器学习编译概述(代码片段)

文章目录1.课程简介2.本节课内容大纲3.机器学习编译的定义4.机器学习编译的目标5.为什么要学习机器学习编译?6.机器学习编译的核心要素6.1.备注:抽象和实现7.总结1.课程简介  该门课程是由XGBoost的作者陈天奇进行... 查看详情

《c#零基础入门之百识百例》(四十一)类的定义和使用--鸡兔同笼

C#零基础入门类和对象--类的定义--鸡兔同笼前言一,类的定义1.1类的概念1.1类的成员1.3类的定义二,类的使用2.1new关键字2.2对象的创建2.3类的成员调用三,实例练习--鸡兔同笼3.1题目描述3.2问题分析3.3参考代码前言本文属于C#零... 查看详情

java:effectivejava学习笔记之接口只用于定义类型类层次优于标签类(代码片段)

Java接口只用于定义类型1、接口只用于定义类型1.1、常量接口2、类层次优于标签类1、接口只用于定义类型当类实现接口时,接口就充当可以引用这个类的实例的类型。因此,类实现了接口,就表明可以对这个类的实... 查看详情

typescript入门学习之路(代码片段)

TypeScript学习之路TypeScript学习之路安装typescript环境typescript起步typescript开发工具vscode自动编译.ts文件typescript中的数据类型typescript中的函数typescript中类的定义继承javascript中的继承typescript中的继承typescript类的静态属性和静态方法t... 查看详情

java学习笔记枚举类(代码片段)

1、枚举类的说明枚举类的理解:类的对象只有有限个,确定的。我们称此类为枚举类当需要定义一组常量时,强烈建议使用枚举类如果枚举类中只一个对象,则可以作为单例模式的实现方式。2、自定义枚举类//自... 查看详情

java之jvm介绍(学习笔记入门)(代码片段)

为自己的学习笔记,图形说话java之所以这么强大是因为跨平台,最直接的就是jvm,每天我们都是写代码,CV大法。java->lcass-->jvm是如何演变呢?中间发生了啥?一、整个java的演变 图直观的看到如下:从... 查看详情

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

因为对Python很熟悉,看着Java的各种字符串操作就不自觉的代入Python的实现方法上,于是就将Java实现方式与Python实现方式都写下来了。先说一下总结,Java的字符串类String本身定义了一些简单的字符串操作,字符串常用操作有:1.取... 查看详情

swift学习笔记之---函数

函数函数是执行特定任务的代码自包含块,给定一个函数名称标识,当执行其任务的时就可以用这个表示来进行"调用"。函数的声明与调用当定义一个函数的时候,可以为其定义一个或多个命名,定义类型值... 查看详情

《c#零基础入门之百识百例》(四十二)类的成员--模拟计算器

C#零基础入门类和对象--类的成员--模拟计算器前言一,访问修饰符1.1概念介绍1.2使用说明二,成员定义1.1数据成员定义2.2函数成员定义三,实例练习--模拟计算器3.1题目描述3.2问题分析3.3参考代码前言本文属于C#零基础入门之百... 查看详情

java入门之collection集合笔记(35)(代码片段)

Collection集合一、集合类体系结构二、Collection集合的概述三、Collection集合常用方法1、add——添加元素2、remove——移除指定元素3、clear——清空集合中所有元素4、contains——判断集合是否存在某个元素5、isEmpty——判断集合是否... 查看详情

java:java学习笔记之reentrantlock的简单理解和使用(代码片段)

ReentrantLockReentrantLock1、相关知识1.1公平锁和非公平锁1.2可重入锁1.3、CAS算法2、背景、定义和特征2.1、背景2.2、定义2.3、特征3、基本结构4、基本使用4.1、解决背景问题4.2、重入锁使用4.3、公平锁使用4.4、可中断使用4.5、可限时使... 查看详情

java学习笔记3.4.3static关键字-静态代码块

文章目录零、本讲学习目标一、static关键字的用处二、静态代码块(一)静态代码块的定义1、什么是代码块2、什么是静态代码块(二)静态代码块执行情况(三)静态代码块的作用(四)静态代码块案例演示三、了解Math类的静... 查看详情

并发编程系列之futuretask源码学习笔记(代码片段)

并发编程系列之FutureTask源码学习笔记1、什么是FutureTask类?在上一章节的学习中,我们知道了Future类的基本用法,知道了Future其实就是为了监控线程任务执行的,接着本博客继续学习FutureTask。然后什么是FutureTask... 查看详情

java学习笔记

为什么JAVA文件中只能含有一个Public类?   java程序是从一个public类的main函数开始执行的,(其实是main线程),就像C程序是从main()函数开始执行一样。只能有一个public类是为了给类装载器提供方便。一个public类只能定义在以它... 查看详情

java之java代码的执行机制

...class文件,这种机制通常被称为Java源码编译机制。1、JVM定义了class文件的格式,但是并没有定义如何将java源码编译为class文件,各个厂商在实现JDK时候通常会将符合java语言规范的源码编译为class文件的编译器,如JDK就是javacjavac... 查看详情

java小白入门200例79之java类的封装(代码片段)

作者简介作者名:编程界明世隐简介:CSDN博客专家,从事软件开发多年,精通Java、JavaScript,博主也是从零开始一步步把学习成长、深知学习和积累的重要性,喜欢跟广大ADC一起打野升级,欢迎您关注&... 查看详情