java笔记

Java课堂笔记

 
// 单行注释
/

/ 多行注释


 标识符由数字,字母,下划线(_),以及$组成
 注:数字不能做为标识符的开始 如:1ab
 
 关键字:只有特殊含义的标识符  如:int , void...
 
 用户自定义的标识符:由用户按标识符构成规则生成的非保留字符  如:abc...

命名规则:Java类命名规则:类名字母大写,如果多个单词组合,则每个单词首字母大写(大驼峰命名法)
HelloWord    ,  Demo
小驼峰命名法:除了第一个单词外,其他单词首字母大写。类似xxxYyyZzz


变量名:
 语法:变量类型  变量名字 赋值符号  值

        int age; //声明变量,不赋值
        age = 0;//声明变量之后赋值
        String name = "龙座";//声明变量,赋值

        //修改变量值(重新赋值)
        age = 32;
        name = "艾莫";

 int 2num; (非法命名)
 int n1, n2, n3, n4;//批量命名
       
       int number;
       int number;   (不能重复声明)        
        

     变量的作用域:
     全局变量:
     定义在方法(函数)和代码块之外的变量
     局部变量:
     定义在方法或代码块之外的变量
 
    //定义全局变量
    int age;
    String name = "龙座";
    //静态变量
    static int number;

    public static void main(String[] args) {
        //定义局部变量
        int age;
       

java常量:程序的整个运行中保持不变的量

public class Deom01 {
    //成员常量
    final double PI = 301415926;
    //静态常量,使用final static关键字修饰
    final static float price = 99.9F;
    //成员常量和静态常量再定义同时必需初始化
    //final static long bigData;   变量bigData没有初始化

    public static void main(String[] args){
        定义常量,使用关键字final
        final int pi = 3;
        // 常量一旦被定义赋值,则不可再被修改

// pi = 6; Variable 'name' might already have been assigned to

        // 局部常量
        final String name;
        name = "大锤";

        //name = "张三"; // Variable 'name' might already have been assigned to


        final long n1;
//        final static long n2 = 3L; 错误写法
    }
}

 十进制
 int num = 12;
        、
 八进制
 int num1 = 025;
        
 十六进制
 int num2 = 0x5d8e;
        
 科学计数法:1.75e5   注:其中e或E之前必有数字,且e或E之后必为整数

定义常量,使用关键字final
        final int pi = 3;
        // 常量一旦被定义赋值,则不可再被修改

// pi = 6; Variable 'name' might already have been assigned to

        // 局部常量
        final String name;
        name = "大锤";

        //name = "张三"; // Variable 'name' might already have been assigned to


        final long n1;
//        final static long n2 = 3L; 错误写法
 
Java中的数据类型:
1、基本数据类型(八种)
byte(字节型【1字节】)、short(短整型)、int(整形)、long(长整型)、float(单精度浮点型)、double(双精度浮点型)
char(字符型)、boolean(布尔型)
2、引用数据类型
除了基本数据类型,其他全部是引用数类型,如:String、数组等

package com.zpark.day02;

public class Deom02 {
    static String name;

    public static void main(String[] args) {
        // 字节型
        byte by = 127;
        // 短整型
        short sh = 56;
        // 整形
        int num = 78946;
        // 长整型,注意: 需要早长整型末尾添加L或者l
        long number = 56L;

        // 单精度浮点型, 注意: 需要早长整型末尾添加F或者f
        float fl = 3.14F;
        float fl1 = 3.1415888888879874243246564564561129f; // 精度丢失

        // 双精度浮点型,java中小数默认是double类型
        double db = 3.14159;

        // 字符型, 字符型的值使用单引号引起来,当值为整形时不需要单引号
        char ch1 = 3;
     

        // 布尔值类型,注意:Java中布尔值类型只有true和false两个值
        boolean bool1 = true;
        boolean bool2 = false;

//引用数据类型:对一个对象的引用,对象包括对象和数组。事实上,引用类型变量就是一个指针
        // null类型    

       String str = null;

        System.out.println(name);

//        int a = null; 报错
    }
}


  基本数据类型大小排行榜
       byte    1字节
       short   2字节
       char    2字节
       int     4字节
       long    8字节
       float   4字节
       double  8字节
 /
二:Java数据类型转换
1:隐式转换(自动类型转换)
需要满足两个条件
(1)、两种数据类型彼此兼容
(2)、目标类型的取值范围大于源数据类型(低级类型数据转换成高级类型数据)
注:小类型数据转为大类型数据
例如 byte 类型向 short 类型转换时,由于 short 类型的取值范围较大,会自动将 byte 转换为 short 类型。
自动转换的规则
(1)、数值型数据的转换:byte → short  → Int  → long  →  float  →  double。
(2)、字符型转换为整型:char  →  int。
注意: char 类型比较特殊,char 自动转换成 int、long、float 和 double,但 byte 和 short 不能自动转换为 char,而且 char 也不能自动转换为 byte 或 short。
2、显式转换(强制类型转换)
(1) 大类型数据转为小类型数据时需要强制转换
(2) 小类型  变量名  =  (需要转换的类型) 大类型;
注意:大类型数据转为小类型数据有可能会造成数据进度丢失和溢出、
注: short类型与char类互相转化需要强制转换
3:不同类型数据相加
4:Java算术运算符
      注意:+可以用作算术运算,也可以做字符串拼接
   任何数据类型与字符串做 + 运算都会变成字符串
1、/
      一元运算符:
  -:取反
  ++:自增
  --:自减
     /
  a ++ 和 ++ a 的区别
a2 = a1 ++;
//先将 a1 的值赋给 a2, a1 再自增 1
a2 = ++ a1;
//先将 a1 的值自增 1 ,再赋值给a2;
a --  和 -- a 同理
2、二元运算符
/
   Java 语言中算术运算符的功能是进行算术运算,
   除了经常使用的加(+)、减(-)、乘(``)和除(\)外,
   还有取模运算(%)。加(+)、减(-)、乘(``)、除(\)
   和我们平常接触的数学运算具有相同的含义
  /
注意: Java 语言算术运算符的优先级是先乘除后加减。
       如果在一个表达式中的多个算术运算符的优先级别相同,例如“a-b+c”,此时将按照运算符的结合方向决定顺序。算术运算符的结合方向都是“从左至右”,即先左后右。
3、算术赋值运算符
/
   java中赋值运算符:
   =:赋值符号
   +=:如, num += 2;  -----> 本质:num = num + 2;
   -=: 如, num -= 2;  -----> 本质:num = num - 2;
   =: 如, num = 2;  -----> 本质:num = num  2;
   /=: 如, num /= 2;  -----> 本质:num = num / 2;
   %=: 如, num %= 2;  -----> 本质:num = num % 2;
  /
4、 Java赋值运算符
其语法格式如下所示:
变量名称 = 表达式内容

注:在 Java 语言中,“变量名称”和“表达式”内容的类型必须匹配,如果类型不匹配则需要自动转化为对应的类型。
5、java中逻辑运算符:
/
   java中逻辑运算符:
        与、或、非
        &&(短路与):如:a && b, 如果ab全部为true则结果为true,否则为false
        ||(短路或):如:a || b, a或者b有一个为true,或者ab均为true,则为true,否则为false
        !:a为true,则结果为false,a为false,则结果为true
  /
/
    && 与 & 区别:如果 a 为 false,则不计算 b(因为不论 b 为何值,结果都为 false)
    || 与 | 区别:如果 a 为 true,则不计算 b(因为不论 b 为何值,结果都为 true)
  /
逻辑运算符的优先级:
!运算级别最高,&& 运算高于 || 运算。!运算符的优先级高于算术运算符,而 && 和 || 运算则低于关系运算符。
6、关系运算符
/    ==:对等于
        !=:不等于
        >:大于
       <:小于
       >=:大于等于
       <=:小于等于
 
      注意:关系运算符的结果为布尔值类型
 /
(1)当引用数据类型使用==和!=做比较运算时的区别:
String对象的创建:
1):直接赋一个字面量: String str1 = “ABCD”;
2):通过构造器构造:String str = new String(“ABCD”);
三:java扫描器
/ java扫描器:用户从控制台输入数据,后台Java程序接收
 /
// 创建扫描器对象
Scanner scan = new Scanner(System.in);

      1、当遇到空格或者回车的时候 next()方法停止读取
      2、当遇到回车的时候 nextLine()方法停止读取,读取整行数据

一、    if else 语句
1、if 结构
if (条件表达式) {
    语句块;
}
(1)条件表达式:条件表达式可以是任意一种逻辑表达式,最后返回的结果必须是一个布尔值。
(2)语句块:该语句块可以是一条语句也可以是多条语句。如果仅有一条语句,可省略条件语句中的大括号 {}。

单分支结构:
     if () {

     }
2、if-else 结构
双分支结构
 if语句:
      if (条件表达式) {
 // 条件为true执行
 // 代码块
      } else {
 // 条件为false执行
      }

3、多条件 if-else-if 语句
多分支结构:
      if () {

      }else if () {

      }else if () {

      }....{

      }else{
// 最后的else语句可要可不要
      }
4、嵌套 if 的使用
if(表达式1) {
    if(表达式2) {
        语句块1;
    } else {
        语句块2;
    }
} else {
    if(表达式3) {
        语句块3;
    } else if(表达式4) {
        语句块4;
    } else {
        if(表达式n) {
   语句块n;
        } else {
   语句块n+1;
        }
    }
}

5、三目运算符
三木运算语法(本质:if语句)
       条件表达式 ? 表达式1 : 表达式2
 当表达式结果true,执行表达式1,否则执行表达式2

 表达式 ? (条件表达式1 ? 表达式1 : 表达式2) : (条件表达式2 ? 表达式1 : 表达式2)

三目运算符使用注意:
在使用条件运算符时,还应该注意优先级问题,例如下面的表达式:

x>y ? x-=y : x+=y;

在编译时会出现语法错误,因为条件运算符优先于赋值运算符,上面的语句实际等价于:

(x>y ? x-=y : x)+=y;

而运算符“+=”是赋值运算符,该运算符要求左操作数应该是一个变量,因此出现错误。为了避免这类错误,可以使用括号“0”来加以区分。例如,下面是正确的表达式。

(x>y) ? (x-=y): (x+=y);

二、    switch case语句
switch(表达式) {
    case 值1:
        语句块1;
        break;
    case 值2:
        语句块2;
        break;
    …
    case 值n:
        语句块n;
        break;
    default:
        语句块n+1;
    break;
}
(1)case
表示“情况,情形”,case 标签可以是:
        1、类型为 char、byte、 short 或 int 的常量表达式。
        2、枚举常量。
        3、从 Java SE 7 开始, case 标签还可以是字符串字面量。
注意:重复的 case 值是不允许的。

(2)default
表示“默认”,即其他情况都不满足。default 后要紧跟冒号,default 块和 case 块的先后顺序可以变动,不会影响程序执行结果。通常,default 块放在末尾,也可以省略不写。

(3)break
表示“停止”,即跳出当前结构。
如果在 case 分支语句的末尾没有 break 语句,有可能触发多个 case 分支。那么就会接着执行下一个 case 分支语句。

三、    while 和 do while 循环
1、while循环:
      语法:
 while (循环条件) {
     循环体
 }
注:while语句是先判断的循环结构,该语句需要判断一个测试条件,如果该条件为真,则执行循环语句(循环语句可以是一条或多条),否则跳出循环。

2、do-while 语句
do.while循环
      语法:
 do{
     循环体
 } while (循环条件);
特点:(1)先执行循环体,然后判断循环条件是否成立。
     (2)至少执行一次循环体    
while循环与do...while循环的区别:
      1、while是先判断后执行,do...while循环是先执行然后再判断
      2、do...while循环至少执行一次
 while循环与do...while的特点:都是循环执行某一语句,循环次数素不固定

四、    for循环
1、for循环:
      语法:
     for (表达式1; 表达式2; 表达式3) {
循环体
     }
      特点:循环次数固定
注意:(1)for 关键字后面括号中的 3 个表达式必须用“;”隔开。for 循环中的这 3 部分以及大括号中使循环体必需的 4 个组成部分完美地结合在一起,简单明了。
(2)for 循环语句执行的过程为:首先执行表达式 1 进行初始化,然后判断表达式 2 的值是否为 true,如果为 true,则执行循环体语句块;否则直接退出循环。最后执行表达式 3,改变循环变量的值,至此完成一次循环。
补:
foreach 语句的用法
1)foreach语法:
      for(迭代变量类型 变量的名字 :需要遍历(迭代)的对象){
 语句块;
      }
2)break语句:作用:结束当前循环
3)continue; // 结束本次循环,强制进入下一次循环
4)/
      定义方法的语法:
  修饰符  返回值类型   方法名(参数1,参数2...) { 方法体... }
     /

    // 自定义方法输出
    // 无返回值。有参数
    public static void print(String str){
        System.out.println(str);
    }

    // 定义有返回值的方法,但是没有参数
    int fun1(){
        // return关键字的作用:1、结束方法的执行。2、将方法的执行结果返回给调用者
        return 12;
    }

    // 有参有返回值
    String fun2(int[] array, double dou, long num, Date time){

        return "有参有返回值";
    }

    // 无参无返回值的方法
    void fun3(){

}
5)方法(函数)的类型:
  1、无参无返回值
      修饰符  void  方法名(){ 方法体 }
  2、无参有返回值
      修饰符   返回值类型   方法名(){ 方法体}
  3、有参无返回值
      修饰符   void   方法名(参数1, 参数2,....){ 方法体}
  4、有参有返回值
      修饰符   返回值类型  方法名(参数1, 参数2,....){ 方法体}
6)方法重载:
  重载就是在一个类中,有相同的函数名称,但参数列表不相同的方法。
       注意:
  方法重载只与方法名字和参数列表有关,与方法返回值类型无关
       方法签名:方法名字 + 参数列表
       什么是程序?
       答:程序 = 算法 + 数据结构

五:数组
1、    数组定义:
    用来存放相同类型的一组数据
      数组下标从0开始,对数组元素进行操作是通过数组的下标(索引)
      数组一旦被创建,则数组的长度不可被修改
    语法:
 静态创建数组
 数据类型[] 数组名 = {值1,值2....}
 数据类型 数组名[] = {值1,值2....}
 动态创建数组
 数据类型[] 数组名 = new 数据类型[数组长度]
 数据类型 数组名[] = new 数据类型[数组长度]
2、静态创建数组,特点:创建数组的同时给数组元素赋值

3、动态创建数组,特点创建数组时指定数组的长度

注:数组元素必须是相同类型的,不允许出现混合类型。
4、数组的边界:
    数组的下标合法区间为:[0,length-1],如果在此范围之外将会报错,这种情况称为数组下标越界


六、生成随机数
  1、Random random = new Random();
 生成指定范围内的随机数 random.nextInt()
  2、double random = Math.random();
 生成随机数的范围 0.0 - 1.0,但永远到不了1


二维数组:

定义一个二维数组:
类型 数组名[常量表达式][常量表达式] 
int arr [][]
静态初始化:
类型 数组名 = 
{{元素1,元素2…}
,{元素1,元素2…}
,{元素1,元素2…}…}; 

int arr[][]=
{{1,2,3,4,5},{1,2,3,4,5},{1,2,3,4,5}};
动态初始化:类型 数组名 = 
new 类型 [行][列] 
int arr [][] = new int [11][11];
     
数组的复制:
      System.arraycopy(arr, start, dist, index, length)

1、二维数组其实就是一个特殊的一维数组,一维数组中每个元素就是一个一维数组
2、三维数组又是一个特殊的二维数组
其他排序算法

选择排序算法:
每一趟从待排序的数据元素中选出最小(或最大)的一个元素;顺序放在已排好的数列的最后,直到全部待排序的数据元素排完。选择排序是不稳定的排序法

把稀疏数组的[0][0]位置和[0][1]的数值恢复成原始数组的行数和列数,接着使用for循环将稀疏数组的非0数据赋给新的数组。 最后使用for增强循环遍历原始数组,输出结果!

稀疏数组转二维数组:

1.先读稀疏数组第一行,根据第一行的数据创建原始的二维数组。
2.再读稀疏数组的后几行数据并赋给原始的二维数组即可。

java笔记5

1、 *   构造方法语法结构:

             【修饰符列表】 构造方法名 (形式参数列表){
    构造方法体; }

      注:对于构造方法,“返回值类型”不需要指定,并且也不能写void。方法名必须要和类名保持一致。

 2、构造方法的作用?

      *   创建对象。

      *   创建对象的同时,初始化实例变量的内存空间。

3、构造方法应该怎么调用?

      *   普通方法是这样调用的:方法修饰符中有static的时候:类名.方法名(实参列表)

方法修饰符中没有static的时候:引用.方法名(实参列表)

      *   new 构造方法名(实参列表)

4、构造方法调用执行之后,有返回值吗?

         每一个构造方法实际上执行结束之后都有返回值,但是这个“return 值;”这样的语句不需要写,构造方法结束的时候Java程序自动返回值,并且返回值类型是构造方法所在类的类型。由于构造方法的返回值类型就是类本身,所以返回值类型不需要编写。

5、当一个类中没有定义任何构造方法的话,系统默认给该类提供一个无参数的构造方法,这个构造方法称为缺省构造器。

      而当一个类的构造方法定义出来了,那么系统不再默认为这个类提供缺省构造器。(建议手动为该类提供无参数构造方法,因为无参数构造方法太常用了)

6、构造方法支持重载机制,在一个类中编写多个构造方法,这多个构造方法显然已经构成方法重载机制了。

7、*   成员变量之实例变量,属于对象级别的变量,这种变量必须先有对象才能有实例变量。

      *   实例变量没有手动赋值的时候,系统默认赋值,那么这个系统默认赋值是在什么时候完成的呢?

          不是在类加载的时候,因为类加载的时候只加载了代码片段,还没来得及创建对象,所以此时实例变量并没有初始化。

          实际上,实例变量的内存空间是在构造方法执行过程当中完成开辟的,完成初始化的,系统在默认赋值的时候,也是在构造方法执行过程当中完成的赋值。

Java方法重载规则额:
1、方法名必须一致
2、参数列表必须不一致(参数类型、参数个数、参数排列顺序)
3、方法的返回类型可以相同也可以不同
4、只是返回类型不同不是方法重载
封装的特点:
•    只能通过规定的方法访问数据。
•    隐藏类的实例细节,方便修改和实现。

实现封装的具体步骤如下:
1.    修改属性的可见性来限制对属性的访问,一般设为 private。
2.    为每个属性创建一对赋值(setter)方法和取值(getter)方法,一般设为 public,用于属性的读写。
3.    在赋值和取值方法中,加入属性控制语句(对属性值的合法性进行判断)。
Java笔记06

可以使用static关键字来定义“静态代码块”:
     (1)语法格式:

     static{

     java语句;

   }

(2)静态代码块在类加载时执行,并且只执行一次。

(3)静态代码块在一个类中可以编写多个,并且遵循自上而下的顺序依次执行。

(4)静态代码块的作用是什么?怎么用?用在哪儿?什么时候用?

        -----这当然和具体的需求有关,例如项目中要求在类加载的时刻/时机执行代码完成日志的记录。那么这段记录日志的代码就可以编写到静态代码块当中,完成日志记录。

      -----静态代码块是java为程序员准备一个特殊的时刻这个特殊的时刻被称为类加载时刻。若希望在此刻执行一段特殊的程序,这段程序可以直接放在静态代码块当中。

static是静态的意思,也是全局的意思。static定义的东西,属于全局,与类相关,不与具体实例相关,是类实例之间共享的。

1. 被static修饰的变量属于类变量,可以通过类名.变量名直接引用,而不需要new出一个对象来

2. 被static修饰的方法属于类方法,可以通过类名.方法名直接引用,而不需要new出一个对象来

static与非static的区别:

在内存中存放的位置不同:所有static修饰的属性和方法都放在内存的方法区(内存的方法区相当于常驻内存,如果一个方法或者变量声明为static,可以节约内存,不必要为每个对象实例化的时候分配内存)里,而非静态的都堆放在堆内存中

生命周期不同:静态在类消失后被销毁,非静态在对象销毁后销毁。

final
final关键字有三个东西可以修饰,修饰非抽象类,修饰非抽象方法,修饰引用。

在类的声明中使用final:

使用了final的类不能再派生子类,就是不可以被继承,简称为断子绝孙类。类中的所有方法都不能被重写。有一些java的面试题问,String可不可以被继承,答案是不可以。因为java.lang.String是一个final类。这可以保证String对象方法的调用确实运行的是String类的方法,而不是经其子类重写后的方法。

在方法的声明中使用final:

被定义为final的方法不能被重写,这个方法成为最终方法,但是该方法仍然可以被继承。如果定义类为final,是所有的方法都不能被重写。而我们只需要类中的几个方法不可以被重写,就在方法前面加上final,而且被定义为final的方法执行效率高。final不能修饰构造方法。

在修饰引用中使用final:

如果引用为基本数据类型,这样变量就是常量了,在程序中这样的变量不可以被修改,修改编译器会报错,而且执行效率比普通的变量要高。final的变量如果没有赋予初值的话,其他方法就必须给他赋值,但只能赋值一次。

如果引用为引用数据类型,比如对象,数组,则该对象、数组本身可以修改,但是指向该对象或数组的地址的引用不能修改。

如果引用的是类的成员变量,则必须当场赋值,否则编译会报错。

static和final一起用:final与static final的区别是:final在一个对象类唯一,static final在多个对象中都唯一;一个既是static又是final的域只占据一段不能改变的存储空间,只有一份。

接口的写法
public interface Test {
    public static final String str = "hello world";
    public abstract void function();
}

public interface TestPlus {
    String  str = "hello world";
    void function();
}

abstract只能修饰类和方法,不能修饰变量。
public class Test {
    public static void main(String[] args) {
        Animal a1 = new Animal();  //此行报错
    }
}
//抽象类Animal
abstract class Animal {
}

abstractb不能和final、private、static联合使用,只能单独使用abstract或者联合public abstract使用。

内部类与外部类的关系

a.成员内部类的创建需要依赖于外部类对象-(成员方法必须通过对象调用),在没有外部类实例之前无法创建成员内部类对象

b.内部类与外部类相对独立,不是is a 的关系(发动机-汽车)

c.私有属性的互相访问,内部类可以直接访问外部类,而外部类访问内部类需要内部类的对象来访问

d.创建内部类的语法

1.在外部类内部创建内部类对象(Inner inner = new Inner())

2.在外部类外部创建内部类对象,外部类.内部类 inner = new Outter().new Inner();

e.在内部类内部使用隐藏的外部类对象(隐藏的this)

静态内部类
        定义在外部类的内部,使用static修饰,类比静态方法,静态内部类不需要外部类对象产生就能使用,不能访问外部类的成员域,但能访问静态域
静态内部类的创建语法:

1.外部类内部:与成员内部类一样

2.外部类外部:StaticInnerClass.Inner inner = new StaticInnerClass.Inner();

3、方法内部类
定义在方法内部:类比局部变量

a.对外部完全隐藏,因此方法内部类不能有任何访问修饰符

b.方法内部类没有访问形参是,这个形参是可以在方法中随意修改的,一旦方法内部类中使用了形参,这个形参必须被声明为final。

4、匿名内部类
a.必须继承一个抽象类或者实现一个接口

b.没有构造方法

枚举是一个被命名的整型常数的集合,用于声明一组带标识符的常数。枚举在曰常生活中很常见,例如一个人的性别只能是“男”或者“女”,一周的星期只能是 7 天中的一个等。类似这种当一个变量有几种固定可能的取值时,就可以将它定义为枚举类型。

Java 枚举类使用 enum 关键字来定义,各个常量使用逗号 , 来分割,结尾使用分号;结束
枚举对应英文(enumeration,简写 enum)

枚举是一组常量的集合

枚举属于一种特殊的类,里面只包含一组有限的特定的对象

不需要提供 setXxxx() 方法,因为枚举对象值通常为只读

对枚举对象/属性使用 static+final 共同修饰

static+final 只有修饰基本数据类型、String类型才不会加载类,修饰对象或者方法还是会加载类

final 修饰对象(引用)只是保证引用的指向不变,但不能保证对象本身不变

枚举对象名通常使用全部大写,与常量的命名规范一样

枚举对象根据需要,也可以有多个属性


Java 笔记7
Flappy Bird
•    变量
•    分支语句
•    循环语句
•    面向对象
•    异常处理
•    Random随机数
•    StringBuffer字符串操作
•    IO操作
•    多线程
•    swing组件
•    实现界面背景
•    step首先新建一个class表示背景类BackGround。我们要在该类中,加载背景图片。
•    创建一个包pics,里面先存放背景图:bg.png。
•    先定义一个常量类Constant,专门用于存储程序中的常量。
•    package com.ruby.demo;
•    
•    /**
•     * 常量类
•     * @author ruby
•     *
•     */
•    public class Constant {
•    
•      // 图片路径
•      public static String PATH_PIC = "/pics/";
•    // 背景图片路径
•      public static String PATH_BACKGROUND = PATH_PIC + "bg.png";
•      
•    }
•    


•    整个项目只有这一个背景,所以可以设计为单例模式。
•    通过getResource()方法加载图片资源。

step然后创建一个面板类,上面用于实现背景,小鸟等。GamePanel
这里主要重写paint()方法,将背景图片,显示到面板上。
step创建一个窗体类GameFrame,里面添加刚刚创建的GamePanel对象。
但是首先要在Constant常量类中,设置一些常量:
代码:
// 界面参数
  public static String GAME_TITLE = "飞翔吧小鸟";
  public static int WINDOW_WIDTH = 432;
  public static int WINDOW_HEIGHT = 644;
创建Main类,表示程序的入口
package com.ruby.demo;
/**
 * 程序的入口
 * @author ruby
 *
 */

public class Main {

  public static void main(String[] args) {
    GameFrame frame = new GameFrame();
    frame.initFrame();
  }

}

实现地面移动
思路:

首先得先在Constant常量类中,添加地面的图片路径,并且将地面图片拷贝到pics资源目录下。
然后创建Ground类:package com.ruby.demo;

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;

/**
 * step1:地面类
 * 
 * @author ruby
 *
 */
public class Ground {
  public BufferedImage img = null;// 地面图片
  public int x, y;// 地面绘制的起始坐标
  public int width = 0;// 地面的宽度
  public int height = 0;// 地面的高度
  private static Ground instance = null;

  private Ground() {
    try {
      // 单例模式
      BackGround bg = BackGround.getInstance();
      // ImageIO用于加载图片资源
      // this.getClass().getResource根据当前路径加载图片
      img = ImageIO.read(this.getClass().getResource(Constant.PATH_GROUND));

      // 获取地面图片的长度和高度
      width = img.getWidth();// 获取图片的宽度
      height = img.getHeight();// 获取图片的宽度

      x = 0;
      y = bg.height - height;// 背景高度与地面图片高度的差值就是地面图片的起始Y坐标
      System.out.println("widthGround=" + width + ", heightGround=" + height);
      System.out.println("x=" + x + ", y=" + y);

    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  // 实现懒汉式
  public static Ground getInstance() {
    if (instance == null) {
      instance = new Ground();
    }
    return instance;
  }
}
在该类中要计算出地面的坐标点x和y。
x为0即可,而y的值为背景图片的高度减去地面图片的高度。
然后添加一个地面移动的方法
Java中将数字转换成字符串共有3中方法
public class IntToString {
    public static void main(String[] args) {
        Integer num = 456;

        //方式1
        String str1 = String.valueOf(num);
        System.out.println("方式1的结果:" + new StringBuilder(str1).reverse().toString());

        //方式2
        String str2 = Integer.toString(num);
        System.out.println("方式1的结果:" + str2);

        //方式3
        String str3 = num + "";
        System.out.println("方式1的结果:" + str3);
    }
}

Java 字符串拼接
方式一:
  使用运算符”+“
1 String s1 = "abc";
2 String s2 = "def";
3 String s3 = "abc" + "def";
4 String s4 = "abc" + s2;
5 String s5 = s1 + s2;
方式二:
  使用 concat()
String s1 = "abc";
String s2 = "def ";
String s3 = s1.concat(s2);

字符串截取
常用方法
方法一:split(),此方法返回的是一个字符串数组类型;
方法二:substring(),进行字符串截取。

三、常用方法介绍和应用示例:
**方法一:**通过split(),此方法返回的是一个字符串数组类型。
1.只传一个参数:split(String regex)
将正则传入split(),根据给定正则表达式的匹配拆分此字符串。不过通过这种方式截取会有很大的性能损耗,因为分析正则非常耗时。

String str = "AB@CD";
String[] strs = str.split("@");
for(int i=0;i<strs.length;i++){
    System.out.println(strs[i].toString());
}
1
2
3
4
5
运行结果:
AB
CD
1
2
3


字符串转数值
一、字符串 转 数字
        1. 通过 parse 方法

public class StringToFigure {
    public static void main(String[] args) {
        String s = "12.35";
 
        float y1 = Float.parseFloat(s);
        System.out.printf("%f\n", y1);
        double y2 = Double.parseDouble(s);
        System.out.printf("%f\n", y2);
    }
}
        2. 通过 valueOf 方法

public class StringToFigure {
    public static void main(String[] args) {
        String s = "12.35";
 
        float y3 = Float.valueOf(s).floatValue();
        System.out.printf("%f\n", y3);
        double y4 = Double.valueOf(s).doubleValue();
        System.out.printf("%f\n", y4);
    }
}
二、数字 转 字符串
        1. 通过 toString 方法

public class FigureToString {
    public static void main(String[] args){
        int i = 1234;
        float f = 12.34f;
        double d = 123.4;
 
        String s1 = Integer.toString(i);
        String s2 = Float.toString(f);
        String s3 = Double.toString(d);
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s3);
    }
}
        2. 通过 String 类的 valueOf 方法

public class FigureToString {
    public static void main(String[] args){
        int i = 1234;
        float f = 12.34f;
        double d = 123.4;
 
        String s4 = String.valueOf(i);
        String s5 = String.valueOf(f);
        String s6 = String.valueOf(d);
        System.out.println(s4);
        System.out.println(s5);
        System.out.println(s6);
    }

Java笔记

字符串替换

String 类提供了 3 种字符串替换方法,分别是 replace()、replaceFirst() 和 replaceAll()

replace() 方法
replace()方法用于将目标字符串中的指定字符(串)替换成新的字符(串)replace(String oldChar, String newChar)

replaceFirst() 方法
replaceFirst()方法用于将目标字符串中匹配某正则表达式的第一个子字符串替换成新的字符串replaceFirst(String regex, String replacement) 但与replaceAll()不同的是,只替换第一次出现的字符串。

replaceAll() 方法
replaceAll()方法用于将目标字符串中匹配某正则表达式的所有子字符串替换成新的字符串replaceAll(String regex, String replacement)

Java字符串替换指定位置的字符
可以使用StringBuffer定义字符串,之后使用replace方法替换指定位置的字符串为指定的字符串内容,如下代码:
public class Demo1 {
public static void main(String[] args) {
StringBuffer buffer = new StringBuffer(“123456”);
System.out.println(buffer.toString());//输出123456
buffer.replace(0, 1, “a”);
System.out.println(buffer.toString());//输出a23456
}
}

StringBuffer 类提供了 3 个构造方法来创建一个字符串,如下所示:
•    StringBuffer() 构造一个空的字符串缓冲区,并且初始化为 16 个字符的容量。
•    StringBuffer(int length) 创建一个空的字符串缓冲区,并且初始化为指定长度 length 的容量。
•    StringBuffer(String str) 创建一个字符串缓冲区,并将其内容初始化为指定的字符串内容 str,字符串缓冲区的初始容量为 16 加上字符串 str 的长度。
•    // 定义一个空的字符串缓冲区,含有16个字符的容量
•    StringBuffer str1 = new StringBuffer();
•    
•    // 定义一个含有10个字符容量的字符串缓冲区
•    StringBuffer str2 = new StringBuffer(10);
•    
•    // 定义一个含有(16+4)的字符串缓冲区,"青春无悔"为4个字符
•    StringBuffer str3 = new StringBuffer("青春无悔");
•    /*
•    *输出字符串的容量大小
•    *capacity()方法返回字符串的容量大小
•    */
•    System.out.println(str1.capacity());    // 输出 16
•    System.out.println(str2.capacity());    // 输出 10
•    System.out.println(str3.capacity());    // 输出 20


字符串分割截取

方法一:通过substring()截取字符串
1. 只传入一个参数 substring(int beginIndex)
传一个参数,含义为将字符串从索引号为beginIndex开始截取,一直到字符串末尾。注意第一个字符的索引值为零,截取时包含索引beginIndex的字符;示例代码如下:
 

String oldStr = "zifu截取练习ing";
    String str = oldStr.substring(5);
    System.out.println(str);
    运行结果:
    取练习ing
2.传入两个参数 substring(int beginIndex, int endIndex)
从索引号beginIndex开始到索引号endIndex结束,返回结果包含索引为beginIndex的字符,不包含索引endIndex的字符;示例代码如下:

String oldStr = "zifu截取练习ing";
 String str = oldStr.substring(0,5);
 System.out.println(str);
 运行结果:
 zifu截
方法二: 通过split()切割字符串,返回结果为字符串数组
1.只传一个参数:split(String regex)
参数支持正则或普通字符,根据给定正则表达式或字符匹配拆分此字符串。示例代码如下:

String oldStr = "China,Japan,美国,俄罗斯";
String[] strs = oldStr.split(",");//根据,切分字符串
for(int i = 0;i < strs.length; i++){
    System.out.println(strs[i]);
}
运行结果:
China
Japan
美国
俄罗斯

2.传入两个参数:split(String regex,int limit)
regex正则表达式分隔符。limit 分割的份数。根据正则表达式或者字符和想要分割的份数来拆分此字符串。示例代码如下:

String oldStr = "China,Japan,美国,俄罗斯";
String[] strs = oldStr.split(",",2);//根据,切分字符串;切两份
for(int i = 0;i < strs.length; i++){
    System.out.println(strs[i]);
}
运行结果:
China
Japan,美国,俄罗斯


在给定的字符串中查找字符或字符串是比较常见的操作。字符串查找分为两种形式:一种是在字符串中获取匹配字符(串)的索引值,另一种是在字符串中获取指定索引位置的字符。


根据字符查找

String 类的 indexOf() 方法和 lastlndexOf() 方法用于在字符串中获取匹配字符(串)的索引值。

1. indexOf() 方法

indexOf() 方法用于返回字符(串)在指定字符串中首次出现的索引位置,如果能找到,则返回索引值,否则返回 -1。该方法主要有两种重载形式:

str.indexOf(value)

str.indexOf(value,int fromIndex)

其中,str 表示指定字符串;value 表示待查找的字符(串);fromIndex 表示查找时的起始索引,如果不指定 fromIndex,则默认从指定字符串中的开始位置(即 fromIndex 默认为 0)开始查找。

下列代码在字符串“Hello Java”中查找字母 v 的索引位置。

String s = "Hello Java";

int size = s.indexOf('v'); // size的结果为8
public static void main(String[] args) {

String words = "today,monday,sunday";

System.out.println("原始字符串是'"+words+"'");

System.out.println("indexOf(\"day\")结果:"+words.indexOf("day"));

System.out.println("indexOf(\"day\",5)结果:"+words.indexOf("day",5));

System.out.println("indexOf(\"o\")结果:"+words.indexOf("o"));

System.out.println("indexOf(\"o\",6)结果:"+words.indexOf("o",6));

}

运行后的输出结果如下:

原始字符串是'today,monday,sunday'

indexOf("day")结果:2

indexOf("day",5)结果:9

indexOf("o")结果:1

indexOf("o",6)结果:7

字符串处理
1、indexof(String s)

s为要搜索的字符串,如果查找到了就返回第一个匹配到的索引位置,如果没有匹配到就返回-1

String str = "ljavadfjsdfhgjjfsjavajfdsj";
        System.out.println(str.indexOf("java"));
2、indexof(String s,int n)

s为要搜索的字符串,n为开始索引的位置,如果没有匹配到就返回-1

3、lastIndexof(String s)

返回最后一个指定字符串匹配到的位置,没有就返回-1

4、startWith(String s)

判断字符串是否以指定的字符串开头,返回类型为boolean类型

5、endsWith(String s)

判断字符串是否以指定的字符串结尾,返回类型为boolean类型

6、trim()

用于删除字符串首尾的空格

7、split(String s)

根据指定字符串分割原字符串,结果返回一个数组

8、subString(int n)

用于分割字符串,结果返回一个新的字符串,此字符串可与indexof配合分割字符串

9、contains(String s)

查找字符串中是否包含s,结果返回boolean类型
1 StringBuilder类型
概述:用来表示字符串的类型
特点:
(1)是一个可变的字符序列
类型底层也是通过一个字符数组来维护的数据,维护的数组没有private修饰,而且类中提供了一些公共修改数组值的方法。
(2)在lang包不需要导包
1.1 StringBuilder构造方法
函数名    解释
StringBuilder()    创建一个初始值为空的字符串对象,数组的初始大小为 16
StringBuilder(int c)    创建一个初始值为空的字符串对象,数组的初始大小是c
StringBuilder(String str)    创建一个初始值为str的字符串对象,数组初始大小为str.len+16
1.2 StringBuilder获取长度的方法
概述:StringBuilder对象中维护的是一个字符数组,所以可以获取字符数组的长度和元素的个数。

函数名    解释
capacity()    返回对象的初始容量
length()    返回字符串对象长度
1.3 StringBuilder类型中常用的方法
1、增加方法:

函数名    解释
append(int i)    在字符串基础上追加数据,可以加任何类型的数据
insert(int offset, char c)    在指定索引添加数据
如果对象中维护的数组容量不够存储,就自动扩容数组
扩容方式:原有的长度*2 + 2
添加的索引范围:0----length

2、删除方法:

函数名    解释
delete(int start, int end)    删除从start开始到end-1结束的字符
deleteCharAt(int index)    删除指定索引位置上的字符
3、替换方法:

函数名    解释
replace(int start, int end, String str)    将指定索引范围的字符换成新的字符串
4、反转方法:

函数名    解释
reverse()    将字符串在本身的基础进行反转
java提供了预定义的日期格式,预定义的日期格式可以满足绝大多数的场景需要。
格式化日期需要两步:
1、通过DateFormat.getDateInstance() 获取一个DateFormat对象。
2、调用DateFormat对象的format方法返回一个String类型的日期。
话不多说看代码:

DateFormat dateInstance = DateFormat.getDateInstance();
 System.out.println(dateInstance.format(new Date()));
1
2
输出结果:

2019-7-7
1
日期格式化样式
在通过DateFormat.getDateInstance()创建实例时使用了默认的日期格式化样式,DateFormat还提供了其他格式化样式。

    public static final int FULL = 0;          //全日期
    public static final int LONG = 1;         //长日期
    public static final int MEDIUM = 2;      //中日期
    public static final int SHORT = 3;      //短日期
    public static final int DEFAULT = MEDIUM;  //默认为中日期
各个日期样式如下(系统为中文环境):

日期样式    示例
FULL    2019年7月7日 星期日
LONG    2019年7月7日
MEDIUM    2019-7-7
SHORT    19-7-7
DEFAULT    2019-7-7
DateFormat.getDateInstance()实例只能够获取年月日信息,如果想要获取时间信息要使用DateFormat.getTimeInstance() 实例,DateFormat.getTimeInstance()使用的常量参数和DateFormat.getDateInstance()相同。    
时间日期样式:    
时间样式    示例
–    –
FULL    下午06时21分51秒 CST
LONG    下午06时23分08秒
MEDIUM    18:23:35
SHORT    下午6:23
DEFAULT    18:23:35
一个简单示例:    
  DateFormat dateInstance = DateFormat.getDateInstance(DateFormat.LONG);
  DateFormat timeInstance = DateFormat.getTimeInstance(DateFormat.LONG);
  System.out.println(dateInstance.format(new Date()) +" "+timeInstance.format(new Date()));
输出结果:

2019年7月7日 下午06时28分40秒

Object类,属于Java.lang包,是默认引入的

        Object类是类层次结构的根类,每个object类使用Object类作为超类(父类)

        所有对象(包括数组)都继承了Object中的方法

介绍Object中典型的几个方法:

equals() :判断某个对象是否与此对象相同

        ==,比较运算符,可以判断基本类型,可以判断引用类型

                如果判断基本数值类型,则判断的是两者数值是否相等

                如果判断引用类型,则判断的是两者的地址是否相同

        equals,Object中的方法,只能用于判断引用类型

                equals()方法默认判断两个引用类型的地址是否相同

// Object中的equals方法
public boolean equals(Object obj) {
    return (this == obj); // 比较的是两个对象的地址
}
        子类中大多会重写equals方法:

                实现根据自己的标准判断两个对象是否相等

// String类中的equals方法:
public boolean equals(Object obj) {
    // 首先判断两个对象的地址是否相同
    if (obj == this) {
        return true; // 说明是同一个对象,直接返回true
    }
    // 判断传入的对象是否是String的子类
    if (obj instanceof String) {
        // 如果是的话,将其从Object类转为String类继续进行比较
        String anotherString = (String)obj;
        int n = value.length; // 记录字符串的长度
        // 两个字符串的长度相同,继续进行比较
        if (n == anotherString.value.length) {
            // 定义字符数组,存储两个字符串中的每个字符
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                // 挨个比较每个字符是否相等
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            // 完成每个字符的比较
            return true;
        }
    }
    // 如果不是String的子类,则直接返回false
    return false;
}

finalize():当垃圾回收器确定不存在对该对象的更多引用时,由垃圾回收期调用该方法

        某个对象没有任何引用的时候,JVM就会认为该对象是一个垃圾对象,使用垃圾回收机制销毁该对象

        某个对象被回收或者销毁时,系统就会自动调用该对象的finalize方法

        垃圾回收机制,是由系统(自己的算法GC)来决定什么时候进行调用,也可以通过System.gc()主动调用垃圾回收机制

        子类重写该方法,可以做一些释放资源的操作:数据库的连接或打开、关闭文件

getClass():返回该对象的运行时类

hashCode():返回该对象的哈希码值

        hashCode()方法可以提高哈希结构容器的效率

        哈希值主要是根据地址号来的,但是不能将哈希值等同于对象的地址

        两个引用如果指向同一对象,即同一地址,则其哈希值相同;如果指向不同的对象,即不同地址,则其哈希值不同

toString():返回该对象的字符串表示


JDK自带记录日志类
日志用来记录程序的运行轨迹,方便查找关键信息,也方便快速定位解决问题。下面介绍 Java 自带的日志工具类 java.util.logging 的使用。

如果要生成简单的日志记录,可以使用全局日志记录器并调用其 info 方法,代码如下:

Logger.getGlobal().info("打印信息");

JDK Logging 把日志分为如下表 7 个级别,等级依次降低。

级别

SEVERE

WARNING

INFO

CONFIG

FINE

FINER

FINEST

调用方法

severe()

warning()

info()

config()

fine()

finer()

finest()

含义

严重

警告

信息

配置

良好

较好

最好

Logger 的默认级别是 INFO,比 INFO 级别低的日志将不显示。Logger 的默认级别定义在 jre 安装目录的 lib 下面。

# Limit the message that are printed on the console to INFO and above.

java.util.logging.ConsoleHandler.level = INFO

所以在默认情况下,日志只显示前三个级别,对于所有的级别有下面几种记录方法:

logger.warning(message);

logger.fine(message);

同时,还可以使用 log 方法指定级别,例如:

logger.log(Level.FINE, message);

例 1

public class Test {

private static Logger log = Logger.getLogger(Test.class.toString());

public static void main(String[] args) {

// 级别依次升高,后面的日志级别会屏蔽之前的级别

log.finest("finest");

log.finer("finer");

log.fine("fine");

log.config("config");

log.info("info");

log.warning("warning");

log.severe("server");

}

}

输出结果为:

十一月 27, 2019 5:13:05 下午 Test.Test main

信息: info

十一月 27, 2019 5:13:05 下午 Test.Test main

警告: warning

十一月 27, 2019 5:13:05 下午 Test.Test main

严重: server
System 类的成员变量
System 类有 3 个静态成员变量,分别是 PrintStream out、InputStream in 和 PrintStream err。

1. PrintStream out

标准输出流。此流已打开并准备接收输出数据。通常,此流对应于显示器输出或者由主机环境或用户指定的另一个输出目标。

例如,编写一行输出数据的典型方式是:

System.out.println(data);
其中,println 方法是属于流类 PrintStream 的方法,而不是 System 中的方法。

2. InputStream in

标准输入流。此流已打开并准备提供输入数据。通常,此流对应于键盘输入或者由主机环境或用户指定的另一个输入源。

3. PrintStream err

标准的错误输出流。其语法与 System.out 类似,不需要提供参数就可输出错误信息。也可以用来输出用户指定的其他信息,包括变量的值。

例 1

编写一个 Java 程序,使用本节介绍的 System 类实现从键盘输入字符并显示出来。 具体实现代码如下:

import java.io.IOException;
public class Test06 {
public static void main(String[] args) {
System.out.println("请输入字符,按回车键结束输入:");
int c;
try {
c = System.in.read(); // 读取输入的字符
while(c != '\r') { // 判断输入的字符是不是回车
System.out.print((char) c); // 输出字符
c = System.in.read();
}
} catch(IOException e) {
System.out.println(e.toString());
} finally {
System.err.println();
}
}
}
以上代码中,System.in.read() 语句读入一个字符,read() 方法是 InputStream 类拥有的方法。变量 c 必须用 int 类型而不能用 char 类型,否则会因为丢失精度而导致编译失败。

以上的程序如果输入汉字将不能正常输出。如果要正常输出汉字,需要把 System.in 声明为 InputStreamReader 类型的实例,最终在 try 语句块中的代码为:

InputStreamReader in = new InputStreamReader(System.in, "GB2312");
c = in.read();
while(c != '\r') {
System.out.print((char) c);
c = in.read();
}
如上述代码所示,语句 InputStreamReader in=new InputStreamReader(System.in,"GB2312") 声明一个新对象 in,它从 Reader 继承而来,此时就可以读入完整的 Unicode 码,显示正常的汉字。
Java异常机制用到的几个关键字:try、catch、finally、throw、throws。


    异常分类
        运行异常(未检查异常):可处理,可不处理
            RuntimeException以及子类都为运行异常
        编译异常(检查异常):必须处理
            Exception以及子类(不包括RuntimeException)都是编译异常
        
    异常处理
        两种处理方式:
            1、抛出异常 throws
                在方法名后 抛出 throws 异常类型

 try        -- 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。
catch   -- 用于捕获异常。catch用来捕获try语句块中发生的异常。
finally  -- finally语句块总是会被执行。
    自定义异常
        定义异常:
            1、创建类 继承异常类
            2、通过构造函数 构造新的异常信息
            
        使用自定义异常:
            throw 异常对象
    
    常见异常:
            ArithmeticException:算术异常
            ArrayIndexOutOfBoundsException:下标索引越界
            NullPointerException:空指针异常(对象是空的)
            ParseException:解析异常
基本数据类型所对应的引⽤数据类型。

        Object可统⼀所有数据,包装类的默认值是null。

基本类型    包装类
byte    Byte
short    Short
int            Integer
long    Long
float    Float
double    Double
char    Character
boolean    Boolean
2、装箱、拆箱
        装箱:基本类型转成引⽤类型

        拆箱:引⽤类型转成基本类型

这里以int和Integer为例:

public class Test {
    public static void main(String[] args) {
        //jdk5以前,手动装箱  int->Integer
        int n1 = 100;
        Integer integer = new Integer(n1);
        Integer integer1 = Integer.valueOf(n1);
        System.out.println(integer1);

        //手动拆箱  Integer->int
        int i = integer.intValue();
        System.out.println(i);
        //jdk5后,自动装箱int->Integer
        int n2 = 200;
        Integer integer2 = n2;//底层使用的是Integer.valueOf(n2)

        //自动拆箱  Integer->int
        int n3 = integer2;//底层使用的是integer.intValue()方法
    }
}


Java 笔记

Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
使用 Lambda 表达式可以使代码变的更加简洁紧凑。
语法
lambda 表达式的语法格式如下:
(parameters) -> expression 或 (parameters) ->{ statements; }
以下是lambda表达式的重要特征:
•    可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
•    可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
•    可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
•    可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定表达式返回了一个数值。
________________________________________
Lambda 表达式实例
Lambda 表达式的简单例子:
// 1. 不需要参数,返回值为 5  
() -> 5  
  
// 2. 接收一个参数(数字类型),返回其2倍的值  
x -> 2 * x  
  
// 3. 接受2个参数(数字),并返回他们的差值  
(x, y) -> x – y  
  
// 4. 接收2个int型整数,返回他们的和  
(int x, int y) -> x + y  
  
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)  
(String s) -> System.out.print(s)
Java程序中的异常介绍
异常就是程序中的错误,但是Java中的程序错误的结构如下:
•    Throwable
o    Error 严重错误,代码无法执行
o    Exception 异常类,异常类又分为两种情况:1、RuntimeException(程序运行时候的异常报错)。2、除RuntimeException外的异常(编译无法通过的异常)。
异常处理
•    throws
它是用来声明异常方法的,不会处理异常。类似于汽车故障了,需要由开车的人来修理,而车子本身是无法修理的。
throws就是汽车故障是,抛出异常的声明,且它只声明方法。谁调用这个方法出错,就由谁来解决这个问题。
•    try-catch
try语句用来执行throws声明的方法,如果该方法出现错误,则执行catch语句中的异常抛出语句。因此,try-catch实际上就成为了修车的人。因为,try语句中调用了throws方法。
•    throw
throw则是用来写在程序代码中间的,用来主动抛出代码异常的。“车太烂了,不修了”,这样代码就直接停止了。因此,throw定义的方法一般用在if语句判断中。
注意:throws主要用来处理代码的逻辑错误。
示例代码
定义一个方法,声明其为throws方法:
package com.xls.YiChang;

public class throwsDome {
public static int div(int x,int y) throws Exception{
return x/y;
}
}
调用上面的方法,如果出现语法错误,则执行catch中的代码:
package com.xls.YiChang;

public class throwsDemoLei {
public static void main(String[] args) {
try {
System.out.println(throwsDome.div(11,2));
}catch (Exception e){
e.printStackTrace();
}
}
}
throw的代码示例;
package com.xls.ThreadDir;

public class throwDome {
public static void main(String[] args) {
int [] arr = null;
printArr(arr);
}
private static void printArr(int[] arr){
if(arr == null){
throw new NullPointerException();
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}


如果 Java 提供的内置异常类型不能满足程序设计的需求,这时我们可以自己设计 Java 类库或框架,其中包括异常类型。实现自定义异常类需要继承 Exception 类或其子类,如果自定义运行时异常类需继承 RuntimeException 类或其子类。

自定义异常的语法形式为:
<class><自定义异常名><extends><Exception>
在编码规范上,一般将自定义异常类的类名命名为 XXXException,其中 XXX 用来代表该异常的作用。

自定义异常类一般包含两个构造方法:一个是无参的默认构造方法,另一个构造方法以字符串的形式接收一个定制的异常消息,并将该消息传递给超类的构造方法。

例如,以下代码创建一个名称为 IntegerRangeException 的自定义异常类:
1.    class IntegerRangeException extends Exception {
2.        public IntegerRangeException() {
3.            super();
4.        }
5.        public IntegerRangeException(String s) {
6.            super(s);
7.        }
8.    }

以上代码创建的自定义异常类 IntegerRangeException 类继承自 Exception 类,在该类中包含两个构造方法。
例 1
编写一个程序,对会员注册时的年龄进行验证,即检测是否在 0~100 岁。

1)这里创建了一个异常类 MyException,并提供两个构造方法。MyException 类的实现代码如下:
1.    public class MyException extends Exception {
2.        public MyException() {
3.            super();
4.        }
5.        public MyException(String str) {
6.            super(str);
7.        }
8.    }

2)接着创建测试类,调用自定义异常类。代码实现如下:
纯文本复制
1.    import java.util.InputMismatchException;
2.    import java.util.Scanner;
3.    public class Test07 {
4.        public static void main(String[] args) {
5.            int age;
6.            Scanner input = new Scanner(System.in);
7.            System.out.println("请输入您的年龄:");
8.            try {
9.                age = input.nextInt();    // 获取年龄
10.                if(age < 0) {
11.                    throw new MyException("您输入的年龄为负数!输入有误!");
12.                } else if(age > 100) {
13.                    throw new MyException("您输入的年龄大于100!输入有误!");
14.                } else {
15.                    System.out.println("您的年龄为:"+age);
16.                }
17.            } catch(InputMismatchException e1) {
18.                System.out.println("输入的年龄不是数字!");
19.            } catch(MyException e2) {
20.                System.out.println(e2.getMessage());
21.            }
22.        }
23.    }

在实际开发中,根据 try catch 语句的执行过程,try 语句块和 catch 语句块有可能不被完全执行,而有些处理代码则要求必须执行。例如,程序在 try 块里打开了一些物理资源(如数据库连接、网络连接和磁盘文件等),这些物理资源都必须显式回收。

Java的垃圾回收机制不会回收任何物理资源,垃圾回收机制只回收堆内存中对象所占用的内存。
所以为了确保一定能回收 try 块中打开的物理资源,异常处理机制提供了 finally 代码块,并且 Java 7 之后提供了自动资源管理(Automatic Resource Management)技术。

finally 语句可以与前面介绍的 try catch 语句块匹配使用,语法格式如下:
1.    try {
2.        // 可能会发生异常的语句
3.    } catch(ExceptionType e) {
4.        // 处理异常语句
5.    } finally {
6.        // 清理代码块
7.    }
对于以上格式,无论是否发生异常(除特殊情况外),finally 语句块中的代码都会被执行。此外,finally 语句也可以和 try 语句匹配使用,其语法格式如下:
1.    try {
2.        // 逻辑代码块
3.    } finally {
4.        // 清理代码块
5.    }
使用 try-catch-finally 语句时需注意以下几点:
1.    异常处理语法结构中只有 try 块是必需的,也就是说,如果没有 try 块,则不能有后面的 catch 块和 finally 块;
2.    catch 块和 finally 块都是可选的,但 catch 块和 finally 块至少出现其中之一,也可以同时出现;
3.    可以有多个 catch 块,捕获父类异常的 catch 块必须位于捕获子类异常的后面;
4.    不能只有 try 块,既没有 catch 块,也没有 finally 块;
5.    多个 catch 块必须位于 try 块之后,finally 块必须位于所有的 catch 块之后。
6.    finally 与 try 语句块匹配的语法格式,此种情况会导致异常丢失,所以不常见。

一、ArrayList集合的概述和基本使用
1.概述
ArrayList是集合的一种实现,Collection是所有集合类的父类。
由于数组在运行期间的长度无法改变,所以有了ArrayList集合。
2.基本使用
创建ArrayList集合
1
2
3    import java.util.ArrayList;//不要忘记导包
//<E>代表泛型,E可以定义为所有的引用类型,例如String、类等
ArrayList<E> list = new ArrayList<>();
将其它类型的集合转为ArrayList
1    ArrayList<String> setList = new ArrayList<>(new HashSet())
常用的方法
(1)添加数据 - add()
1
2    ArrayList<String> list = new ArrayList<>();
list.add("csdn");
(2)获取数据 - get()
1    list.get(i);//i为集合的元素索引
(3)删除数据 - remove()
1    list.remove(i);//i为集合的元素索引
(4)获取集合长度 - size()
1
2    int l = list.size();
System.out.println("集合的长度是:"+l);

LinkedList它的数据存储方式是双向链表,基于链表存储的特性, LinkedList具有查询较慢(顺序访问)但增加/删除较快(虽然要遍历到指定位置, 但是相对于数组存储来说不需要移位)的特点
b, 双向链表的作用, 我们在查询的时候,可以从前往后遍历, 也可以从后往前遍历, 具体使用哪种方式取决于我们要查询的节点是靠后一点还是靠前一点
c, LinkedList内部每个节点用私有内部类Node表示, LinkedList通过first和last引用分别指向链表的第一个和最后一个元素, 当链表为空时, first和last都为null值
d, Node里面有三个元素: item当前节点的值。 next 指向当前节点的后一个节点。prev 指向当前节点的前一个节点
e, LinkedList不存在容量不足的情况。 因为是链表,动态获取内存, 不需要我们去扩容
f, LinkedList可以存储null值
g, LinkedList因为实现了Queue接口, 所以还能当队列使用
Java Collection常用方法
package collection;

import java.util.ArrayList;
import java.util.Collection;

/**
 *  Collection接口常用方法总结,Collection没有直接实现子类,因此采用子接口List的实现类ArrayList做演示
 *  List接口和Set接口继承了Collection接口,所以List的实现类(ArrayList、LinkedList、Vector)还有
 *  Set的实现类HashSet等都可以使用这些方法
 */
public class CollectionMethod {
   public static void main(String[] args) {
      //1、add() 添加元素,这里没有指定类型,可以加各种类型
      Collection list = new ArrayList();
      list.add("jack");
      list.add(10);
      list.add(true);
      System.out.println("list = " + list);

      //2、remove() Collection对象只能指定删除对象删除,List对象还可以指定下标删除,被删除元素会作为返回值
      list.remove(true);
      System.out.println("list = " + list);

      //3、contains() 查找某个元素是否存在
      System.out.println("jack是否存在: " + list.contains("jack"));

      //4、size() 获取元素个数
      System.out.println("list的大小:" + list.size());

      //5、isEmpty() 判断是否为空
      System.out.println("list为空么? " + list.isEmpty());

      //6、clear() 清空数组元素
      list.clear();
      System.out.println("clear以后: " +  list);

      //7、addAll() 一次添加多个元素,参数为集合类型
      Collection list1 = new ArrayList();
      list1.add("Evan");
      list1.add("王颖");
      list.addAll(list1);
      System.out.println("list = " + list);

      //8、containsAll() 一次查找多个元素是否都存在
      System.out.println("list1 是否都在list中么? " + list.containsAll(list1));

      //9、removeAll() 一次删除多个元素 参数同样为集合类型
      list.removeAll(list1);
      System.out.println("删除list1包含元素后list = " + list);

   }
}

Java笔记是由北京大学青鸟教育推出的一款专门针对Java语言的学习工具。它以全面、系统、实践为特点,通过详细的代码示例和清晰的讲解,帮助学习者全面掌握Java编程语言。 Java笔记采用了线上与线下相结合的学习模式。学员可以通过手机、平板电脑、电脑等设备在线学习,还可以在学习过程中随时记录自己的学习笔记。同时,北大青鸟还为学员提供线下实践环境,学员可以在实验室里亲自动手实践所学知识,加深理解和应用。 Java笔记的内容非常全面,包括了Java语言的基本语法、面向对象编程、异常处理、流操作、多线程、数据库操作等众多知识点。除了理论知识,Java笔记还提供了大量的实例代码,可供学员参考和模仿。这样的学习方式既帮助学员理解Java的基本概念,又能让他们运用所学知识解决实际问题。 与此同时,Java笔记还注重学员的互动交流。在学习过程中,学员可以利用笔记功能记录学习心得和疑惑,还可以在论坛上与其他学员进行讨论和交流。这种互动形式既能促进学员之间的学习互助,也能更好地帮助学员理解和应用所学知识。 总之,Java笔记是北大青鸟推出的一款专注于Java语言学习的工具,通过系统的课程设置、丰富的实例代码和互动交流的方式,帮助学员全面掌握Java编程知识,提升编程能力。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值