Xiaoshier Blog

初探 java

第一次学习 java, 学习笔记

安装环境概念

  1. JVM
    java 虚拟机( java virtual machine )

    运行 Java bytecode 的虚拟机, 以堆栈结构机器来进行实做. 有自己完善的硬件架构, 如处理器, 堆栈, 寄存器等, 还有相应的指令系统. JVM 屏蔽了与具体操作系统平台相关的信息, 使得 Java 程序只需生成在 Java 虚拟机上运行的目标代码(字节码), 就可以在多种平台上不加修改地运行. 通过对中央处理器( CPU ) 所执行的软件实现, 实现能执行编译过得 Java 程序码
    理解: 对上提供统一的接口, 对下即操作系统分别进行封装, 实现编写一套代码, 多处使用.

  2. JDK
    java 开发工具包 (java development kit)
    java 开发人员用来编译, 调试程序使用
    包含组件:
    • 用于 Java 开发的组件: javac( 编译器, 将后缀名为.java 的源代码编译成后缀为.class的字节码 ); java(运行工具, 运行.class字节码); jar( 打包工具, 将相关类打包成一个文件); javadoc( 文档生成器, 从源码注释中提取文档, 注释需匹配规范); jdb debugger(调试工具); jps( 显示当前 java 程序运行的进程装填 ); javap( 反编译程序 ); appletviewer( 运行和调试 applet 程序的工具, 不需要使用浏览器 ); javah( 从 java 类生成 c 头文件和 c 源文件. 这些文件提供了连接胶合, 使java 和 c 代码可以进行交互 ); javaws( 运行 JNLP 程序 ); extcheck( 一个检测 jar 包冲突的工具 ); apt( 注释处理工具 ); jhat( java 堆分析工具 ); jstack( 栈跟踪程序 ); jstat( JVM 检测同级工具 ); jstatd( jstat 守护进程); jinfo( 获取 java 进程内存映射信息 ); idlj( IDL-to-Java 编译器. 将 IDL 语言转化为 java 文件 ); policytool( 一个 GUI 的策略文件创建和管理工具 ); jrunscript( 命令行脚本运行 )
    • 完整的 JRE
    • 样例程序, 展示 Java API
  3. JRE
    java 运行时环境 (java runtime environment)
    包括: java 虚拟机, java 基础类库
    普通用户安装来运行 java 程序

安装

安装 JDK

在官网上下载

JDK: Java Development Kit
下载安装

  1. 查询本机 java 和 JDK 版本

    1
    2
    java -version //java 版本
    javac -version //jdk 版本

    查看电脑里都安装了那些版本 jdk

    1
    /usr/libexec/java_home -V

会显示电脑里所有版本 jsk

  1. JDK 版本切换

    • 使用的是 zsh, 所以在 .zshrc 中添加别名进行切换

      1
      vi ~/.zshrc

      添加如下内容

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      # 设置 JDK 7
      export JAVA_7_HOME=`/usr/libexec/java_home -v 1.7`
      # 设置 JDK 8
      export JAVA_8_HOME=`/usr/libexec/java_home -v 1.8`(可确认到具体版本1.8.0_181)

      # 某个项目使用指定版本 jdk8
      export JAVA_HOME = JAVA_8_HOME /your_program_path

      #默认JDK 7, 如果想全局使用某个版本, 将下面改为某个版本
      export JAVA_HOME=$JAVA_7_HOME

      #alias命令动态切换JDK版本
      alias jdk7="export JAVA_HOME=$JAVA_7_HOME"
      alias jdk8="export JAVA_HOME=$JAVA_8_HOME"
    • 执行

      1
      source .zshrc
    • 切换 JDK

      1
      2
      jdk7 //切为1.7版本
      jdk8 //切为1.8版本

homebrew 下载

1
2
brew tap caskroom/versions
brew cask install java8
下载完后包同上, 版本切换同上

编译运行

  1. 编写文件
    存储类型为 .java

    • 类名需要和文件名一致, 不然会报错

      • 正确
        eg: helloWorld.java

        1
        2
        3
        4
        5
        public class helloWorld {
        public class void main (String[] args) {
        System.out.print("hello world");
        }
        }

        编译与运行

        1
        2
        javac helloWorld.java //compile
        java helloWorld //operate
      • 错误
        eg: helloWorld.java 类名为 HelloWorld

        1
        2
        3
        4
        5
        public class HelloWorld {
        public class void main (String[] args) {
        System.out.print("hello world");
        }
        }

        编译与运行

        1
        javac helloWorld.java

        error: helloWorld.java:1: error: class HelloWorld is public, should be declared in a file named HelloWorld.java
        public class HelloWorld{}

  2. 编译

    1
    javac helloWorld.java
  3. 运行

    1
    java helloWorld

知识点

  1. java 一个文件中只包含一个主类, 即用 public 声明的类, 文件名和主类名保持一致
  2. 测试文件与类文件分别放置
  3. 只用编译一个入口文件, 入口文件引用的相关的文件都会被编译, 并且在编译时会去判断正误, 在同一目录下,
  4. 一个文件中, 可以共存多个以 class 声明的类, 在编译时, 会单独编译出该 class 命名的文件, 文件名为该类名

  5. 声明变量
    变量是保存对象的地址, 它指向对象存储的物理位置, 每个实例化的对象, 系统都会给其分配内存, 变量仅是用来是指向该内存地址
    变量可以是对象的状态, 局部变量(声明在方法中的变量), 参数,执行方法的返回值
    此处的 className 是类名, 可以是 java 内建类 eg: String, init, ArrayLiat, etc; 也可以是自定义类

    1
    2
    3
    4
    className objName = new className(); //实例化一个对象, 并赋值给 objName 变量
    eg: String gogo = new String( "I am a string" ); //实例一个字符型对象(传入参数), 赋值给 gogo 的变量
    HelloWorld hello = new HelloWorld();
    className[] objName = new className[length];
  6. 构造函数
    创建实例对象是通过 new 一个构造函数实现的

    • 若没定义构造函数, 编译器会默认为每个类添加一个空的构造函数
    • 定义一个构造函数, 该构造函数名与类名保持一致
    • 可以重载构造函数, 相同的构造函数名, 相同的返回类型, 不同的参数(类型或个数)
  7. 基本类型变量存储在栈中,

  8. 引用型变量名存储在栈中, 赋值内容存储在堆中, 变量名指向堆中的内容

  9. 类存储在代码区

  10. 类中的方法存储在代码区, 只有在执行时才分配内存, 执行结束后内存收回
    同一类的每个对象共享该类的方法

  11. 当编译器看到一个整数时, 会把它当做 int 型

  12. java 的所有函数都是属于某个类的方法, 所以 main 函数也需要有个外壳类, 这个类有可能仅是为了main 函数而建立, 仅为了能够执行 main 函数

  13. 类的成员变量, 未赋值的成员变量, 均有初始值, int 类型为0, string 类型为 null, boolean 为 false, float 类型为 0.0
    方法里的变量则不会有默认初始值

  14. final 指示常量, 只可被赋值一次, 常量一般用大写字母表示

  15. 字符串不可以修改, 赋值出现时拥有自己的内存, 如不可以把” hello”进行修改, 如果想修改变量对应字符串中的内容, 那就只能是获取该变量对应的字符串内容, 对其进行拼接, 再赋值给变量, 相当于将变量的引用指向了另外一个字符串对象;

  16. 数组, 数字型数字默认初始值为0; boolean 型数组默认初始值为 false; object 型数组默认初始值为 null;
    数组一旦创建, 个数是不能改变的

  17. for each loop
    for(type ele : arr){

    ele 是数组元素的值, 而不是指向数组值的索引
    

    }
    所以 for each 是不可以给数组赋值

  18. 数组的拷贝

    • 仅是变量的拷贝, 二者均指向同一内存区域, 即同一个数组对象;
      int[] arr = new int[3];
      int[] copyArr = arr;
    • 拷贝数组并创建新的对象
      int[] copiedNewArr = Arrays.copyOf(arr, arr.length);
  19. 数组初始化
    arrAnonymous = new int[] {1, 2, 3, 4};
    int[] arr = {1, 2, 3, 4};

  20. main( String[] args )方法中的参数, 是用来接收命令行中的参数

  21. 构造器

    • 与类同名
    • 重载
    • 无返回值
    • 使用 new 调用
    • 若类中未定义构造器, 编译器默认添加一个空的构造器
    • 可以传任意个数的参数
  22. 当类需要返回一个可变对象的引用时, 对这个对象进行克隆, 防止在该类对象的引用中, 改变

  23. 哈希值 代表独一无二的对象, 并且指向对象所在的位置

  24. 静态方法
    public static void method() {}
    以下条件可以设置为静态方法

    • 与对象状态无关
    • 只用访问类的静态域
  25. 一个方法可以访问该方法所属类的所有对象的私有数据

  26. 参数传递, 都是值传递,
    基本类型的实参, 是将实参复制一份出来, 再赋值给形参, 在函数内部进行的任何操作都不会影响到实参的值
    对象类型的实参, 是将引用复制一份出来, 再赋值给形参, 在函数内部对实参的操作, 都是同一个对象, 会影响到对象的值. 但是如果是在函数中对参数引用的操作, 则不影响实参的值

  27. this
    在一个构造器中可以使用 this() 调用该类中的另外一个构造器
    class Employee{

    public Employee(double s) {
        String nextId = "hello";
        this.(nextId, s);// 调用下面构造器, 并传入参数
    }
    public Employ(String n, double s) {
    
    }
    

    }

  28. 编译器在编译时不检查目录结构, 源文件开头有包语句, 但不在该包的目录下亦可通过编译, 但在 java 虚拟机中无法运行, 因为虚拟机找不到类文件
    类的路径必须与包名匹配

  29. 子类(派生类/孩子类) extends 超类(父类/基类)
    子类比超类的功能更加丰富