Java_编程机制_0_基础编程

基础编程

基本内容

  1. 注释、控制台互动、导包:

    • 3 种注释:

      // 单行注释
      
      /*
      	多行注释
      */
      
      /**
      	文档注释
      */
      
    • 在控制台输出:

      System.out.println();
      
    • 在控制台输入:

      import java.util.Scanner;
      
      Scanner sc = new Scanner(System.in);
      XXX i = sc.nextXXX();
      //看具体要接收什么,如,字符串就next(),整数就nextInt(),浮点数就nextDouble()
      
    • 导包:

      如果类在 java.lang 包下,则不需要导包,否则需要使用 import 语句进行导入。

  2. 标识符的命名:

    • 语法限制规则:

      • 数字、字母、下划线(_)和美元符($)组成;

      • 不能以数字开头;

      • 不能是关键字;

      • 区分大小写;

    • 规范约定:

      • 小驼峰:(用于变量、属性、方法名)

        • 标识符是一个单词的时候,首字母小写;
        • 标识符由多个单词组成的时候,第一个单词首字母小写,其他单词首字母大写;
      • 大驼峰:(用于类名)

        • 标识符是一个单词的时候,首字母大写;
        • 标识符由多个单词组成的时候,每个单词的首字母大写;
  3. 运算符:

    • 逻辑运算符:

      // 与或非
      	&		|		!
      // 短路与或
      	&&   ||
      
      • 短路与:当左边的为 false 时,结果为 false ,右边直接不执行;

      • 短路或:当左边的为 true 时,结果为 true ,右边直接不执行;

    • 比较是否相等:

      ==
      
      • 对于基本数据类型,比较的是它们的数据值是否相等;

      • 对于引用数据类型,比较的是它们的地址是否相等;

    • 对于字符型数据,也可以直接比较大小,使用的是它们的 ASCII 码值。

    • 三元运算符:

      首先计算关系表达式的值,如果值为 true表达式1的值就是运算结果,如果值为 false表达式2的值就是运算结果。

      关系表达式 ? 表达式1 : 表达式2;
      

数据类型

  1. 数据类型:

    数据大类数据类型内存占用字节数表数范围(用相应包装类的常量属性可看)
    整数byte1-128~127
    short2-215 ~ 215-1(约正负3.2万多)
    int4-231 ~ 231-1 (约正负 21亿多)
    long8-263 ~ 263-1(约正负922亿亿多)
    浮点数float41.4x10-45 ~ 3.4x1038
    double84.9x10-324 ~ 1.8x10308
    字符char20 ~ 65535
    布尔boolean1true,false

    **注意:**对于直接书写在代码中的数字,整数默认会被当作 int 类型存储,小数默认会被当作 double 类型存储。

    • 若要指定其为 long 类型的,则在数字后加 Ll
    • 若要指定其为 float 类型的,则在数字后加 Ff
  2. 变量的数据类型转换:

    • 自动转换:

      • 允许把一个表示数据范围小的数值或者变量赋值给另一个表示数据范围大的变量,数据的类型也就自动转成范围大的那个类型;
      • 不同类型的数据/变量参与算术运算时,结果将自动转为这些变量/数据里面表数范围最大的那个类型;
      byte
      short
      char
      int
      long
      float
      double
    • 强制转换:

      把一个表示数据范围大的数值或者变量赋值给另一个表示数据范围小的变量,会损失精度,语法如下:

      目标数据类型 变量名 = (目标数据类型) 值或者变量;
      

流程控制

  1. if 语句:

    if (关系表达式) {
        语句体;	
    }
    
    if (关系表达式) {
        语句体1;	
    } else {
        语句体2;	
    }
    
    if (关系表达式1) {
        语句体1;	
    } else if (关系表达式2) {
        语句体2;	
    }else {
        语句体n+1;
    }
    
  2. switch 语句:

    switch (表达式) {
      case1:
        		语句体1;
        		break;
      case2:
          	语句体2;
        		break;default:
        		语句体n+1;
        		[break;]
    }
    
    switch (表达式) {
      case1:
      case2:
        ...
        		语句体1;
        		break;
      case 值k:
      case 值k+1:
          	语句体2;
        		break;default:
        		语句体n+1;
        		[break;]
    }
    
  3. for 语句:

    for (初始化语句;条件判断语句;条件控制语句) {
      循环体语句;
    }
    

    for 的死循环写法:

    for (;;) {
     循环体语句;
    }
    
  4. while 语句:

    初始化语句;
    while (条件判断语句) {
      循环体语句;
      条件控制语句;
    }
    

    while 的死循环写法:

    while (true) {
    循环体语句;
    }
    
  5. do…while 语句:

    初始化语句;
    do {
       循环体语句;
       条件控制语句;
    } while (条件判断语句);
    
  6. 说明:

    • 循环语法的区别:

      • for 循环和 while 循环先判断条件是否成立,然后决定是否执行循环体(先判断后执行);

      • do…while 循环先执行一次循环体,然后判断条件是否成立,是否继续执行循环体(先执行后判断);

    • 跳转语句:

      • continue 用在循环中,基于条件控制,跳过某次循环体内容的执行,继续下一次的执行;

      • break 用在循环中,基于条件控制,终止循环体内容的执行,也就是说结束当前的整个循环;

方法

  1. 声明语法基本结构:

    修饰符 返回值类型 方法名(参数列表) {
        方法体...
    }
    
  2. 支持可变参数列表:

    修饰符 返回值类型 方法名(数据类型... 变量名) {
        ...
    }
    
    • 传入的实参会被封装成对应类型的数组,此处的 “变量名” 即为数组引用名,在方法体中使用。

    注意: 在语法要求上,若一个方法有多个参数,且其中包含可变参数,则可变参数必须放在形参列表最后面,如:

    void add(int a, int... b) {
        ...
    }
    
  3. 方法重载:

    • 方法名相同,而传入参数列表不同的方法声明即为方法重载;
    • 对于返回值类型、修饰符等,忽略不看。

修饰符

  1. 权限修饰符:

    被修饰符修饰的成员本类的代码中同一包中的类的代码中不同包的子类的代码中不同包的无关类的代码中
    private允许访问
    缺省(包访问权限)允许访问允许访问
    protected允许访问允许访问允许访问
    public允许访问允许访问允许访问允许访问
  2. 状态修饰符:

    • final :“最终”,可以修饰变量、方法、类。

      • 修饰变量:表明该变量是常量,不能再次被赋值
        • 变量是基本类型:final 修饰指的是基本类型的数据值不能发生改变;
        • 变量是引用类型:final 修饰指的是引用类型的地址值不能发生改变,但是地址里面的内容是可以发生改变的;
      • 修饰方法:表明该方法是最终方法,不能被重写
      • 修饰类:表明该类是最终类,不能被继承
    • static :“静态”,可以修饰成员方法、变量。

      • 绑定“类”本身,为此类的所有对象所共享,可以通过类名调用(推荐)

      • 访问特点:

        • 动态成员方法可以访问静态成员
        • 而静态成员方法只能访问静态成员

数组

定义与使用

  • 数组是一种用于存储多个相同类型数据的存储模型。

  • 声明语法:

    //格式1:
    	数据类型[] 变量名;
    
    //格式2:
    	数据类型 变量名[];
    
  • 操作方法:

    • 通过索引访问元素;

    • length 属性存储数组的长度;

      Java 中数组一经创建,长度不可修改。

初始化

Java 中的数组必须先初始化,然后才能使用。而所谓初始化,就是为数组元素分配内存空间,并为每个数组元素赋值。

  • 静态初始化:

    数据类型[] 变量名 = {数据1, 数据2, ...};
    
  • 动态初始化:

    数据类型[] 变量名 = new 数据类型[数组长度];
    
    • 初始化时只指定数组长度,则系统会为数组元素分配初始值( 0falsenull )。

面向对象特性问题

  1. 数组要求元素的类型必须相同,而在存在继承关系的情况下,使用静态初始化动态初始化两种方式,得出的这个数组的“基准相同类型”是不一样的,后续只有这个“基准相同类型”及其子类的对象能被 set 进数组(索引访问更改某位置的元素)。

    以下举例的代码中: class B extends A

    • 静态初始化的方式下,由被赋值的数组引用变量的类型决定:

      public static void main(String[] args) {
          A[] as1 = {new A(), new A()};
          as1[0] = new A(); // OK
          as1[1] = new B(); // OK
      
          A[] as2 = {new A(), new B()};
          as2[0] = new B(); // OK
      
          A[] as3 = {new B(), new B()};
          as3[0] = new A(); // OK
      
          B[] bs1 = {new B(), new B()};
          bs1[0] = new A(); // not OK!
          
          B[] bs2 = {new A(), new B()}; // not OK!
      }
      
    • 动态初始化的方式下,由 new 关键字后的类型决定:

      public static void main(String[] args) {
          A[] as1 = new A[2];
          as1[0] = new A(); // OK
          as1[1] = new B(); // OK
      
          B[] bs1 = new B[2];
          bs1[0] = new B();
          bs1[1] = new A(); // not OK !
      
          B[] bs2 = new A[2]; // not OK !
      
          A[] as2 = new B[2]; // OK !
          as2[0] = new B(); // OK !
          as2[1] = new A(); // compile OK  &  runtime not OK !!!
      }
      
    • 其中,以上两点的重点区别体现在:

      public static void main(String[] args) {
      
          A[] as3 = {new B(), new B()};
          as3[0] = new A(); // OK
          
          A[] as2 = new B[2];
          as2[0] = new B(); // OK !
          as2[1] = new A(); // compile OK  &  runtime not OK !!!
      
      }
      
  2. 为了让元素方便地使用 Java 的多态特性,数组支持一个特殊的语法——允许把数组对象赋值给其元素的基类的数组引用,并且,用这个基类数组引用配合索引时,代表的是相应元素的基类引用。

    这个本身看起来是离谱的,因为数组对象是数组对象,即是一个容器对象自身,用它持有的对象的继承关系来把容器对象自身赋值给其持有对象的基类数组引用,在逻辑上完全不合理,但 Java 最初就是这么设计的。。。后来是通过集合配合泛型,重新设计了这种用法才在逻辑上合理地解决了问题。

    • 对于动态初始化的情况,从一开始就明确了数组的“基准相同类型”;
    • 对于静态初始化的情况,对于 {数据1, 数据2, ...} ,Java 不允许它直接放入方法调用的实参列表中,必须赋值给一个确定类型的数组引用,再用这个数组引用作为实际参数传入方法中,因为它的“基准相同类型”只有这样才能确定;

    举例如下:

    public class A {
        String mbr = "A's mbr";
    
        void a() {
            System.out.println("A's a-method");
        }
    }
    
    public class B extends A {
        String mbr = "B's mbr";
    
        void a() {
            System.out.println("B's overriding a-method");
        }
    
        void b() {
            System.out.println("B's b-method");
        }
    }
    
    public class JavaSE {
        static void show(A[] as) {
            for (A a : as) {
                System.out.print("属性:" + a.mbr + " | 方法:");
                a.a();
            }
            System.out.println("-----------");
        }
    
        public static void main(String[] args) {
            
            A[] as1 = {new A(), new B()};
            show(as1);
             /* 控制台输出如下:
             属性:A's mbr | 方法:A's a-method
             属性:A's mbr | 方法:B's overriding a-method
             -----------
             */
            
            A[] as2 = new A[2];
            as2[0] = new A();
            as2[1] = new B();
            show(as2);
            /* 控制台输出如下:
            属性:A's mbr | 方法:A's a-method
            属性:A's mbr | 方法:B's overriding a-method
            ----------- 
         	*/
            
            A[] as3 = {new B(), new B()};
            show(as3);
            /* 控制台输出如下:
            属性:A's mbr | 方法:B's overriding a-method
            属性:A's mbr | 方法:B's overriding a-method
            ----------- 
         	*/
            
            A[] as4 = new B[2];
            as4[0] = new B();
            as4[1] = new B();
            show(as4);
            /* 控制台输出如下:
            属性:A's mbr | 方法:B's overriding a-method
            属性:A's mbr | 方法:B's overriding a-method
            ----------- 
         	*/
            
            B[] bs1 = {new B(), new B()};
            show(bs1);
            /* 控制台输出如下:
            属性:A's mbr | 方法:B's overriding a-method
            属性:A's mbr | 方法:B's overriding a-method
            ----------- 
         	*/
            
            B[] bs2 = new B[2];
            bs2[0] = new B();
            bs2[1] = new B();
            show(bs2);
            /* 控制台输出如下:
            属性:A's mbr | 方法:B's overriding a-method
            属性:A's mbr | 方法:B's overriding a-method
            -----------
         	*/
            
            B[] bs3 = {new B(), new B()};
            System.out.print(bs3[0].mbr + " | ");
            bs3[0].a();
            bs3[0].b();
            /* 控制台输出如下:
            B's mbr | B's overriding a-method
    		B's b-method
         	*/
            
        }
    
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值