Java学习

java入门

java三大版本

  • javaSE:标准版(桌面程序,控制台开发…)
  • javaME:嵌入式开发(手机,小家电…)
  • javaEE:E企业级开发(web端,服务器开发…)

Java特性和优势

  • 简单性
  • 面向对象
  • 可移植性(各平台连通)
  • 高性能
  • 分布式
  • 动态性(反射)
  • 多线程
  • 安全性
  • 健壮性

java开发环境搭建

jdk下载与安装

  1. 百度搜索JDK8,找到下载地址
  2. 同意协议
  3. 下载电脑对应的版本
  4. 双击运行安装
  5. 记住安装路径
  6. 配置环境变量
    1. 我的电脑-》右键-》属性
    2. 环境变量-》JAVA_HOME
    3. 配置path变量
  7. 测试JDK是否安装成功
    1. 打开cmd
    2. 输入java-version命令

HelloWorld及简单语法规则

public class Hello{public static void main(String[] args){System.out.println("Hello World");}
}

个人建议用idea来写代码方便很多!!

  • 类名和文件名保持一致
  • 中文名可能会出现乱码的情况
  • 符号都是英文符号

卸载jdk(不需要这个jdk时候删)

  1. 删除Java的安装目录

  2. 删除JAVA_HOME

  3. 删除path下关于Java的目录

  4. Dos执行java-version命令(提示找不到文件即为删除完毕)

IDEA安装与优化

链接:https://pan.baidu.com/s/1AmZzq-05JlADF4IxLZBZHQ
提取码:zcgc

IDEA优化

参考文章https://blog.csdn.net/zeal9s/article/details/83544074

Java基础

注释

注释不会被执行,方便我们在复杂的项目中排查问题

分类

  • 单行注释(//)
public class Main {public static void main(String[] args) {// write your code here}
}
  • 多行注释(/*回车)
public class Main {public static void main(String[] args) {/*多行注释*/}
}
  • 文档注释(/**回车)
public class Main {public static void main(String[] args) {/*** 文本注释*/}
}

标识符与关键字

Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。

标识符注意点

  • 所有的标识符都应该以字母(A-Z或者a-z),美元符($)、或者下划线(_)开始
  • 首字符之后可以是字母(A-Z或者a-z),美元符($)、下划线(_)或者数字的任意字符组合
  • 不能使用关键字作为变量名或方法名
  • 标识符是大小写敏感的

数据类型

强类型语言

要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用

弱类型语言

Java数据类型分为两类

基本类型

  1. 数值类型
  • 整数类型

    byte占1个字节:-128-127

    short占2字节:-32768-32767

    int占4字节:-2147483648-2147483648

    long占8字节:-9223372036854775808-9223372036854775807

  • 浮点类型

    float占4字节

    double占8个字节

  • 字符类型

    char占2个字节

  1. Boolean类型:false&true
public class javatest {public static void main(String[] args) {//整数int num = 10;byte num1 = 10;short num2 = 10;long num3 = 30L;//Long类型要在数字后面加个L//小数float num5 = 50.1F;//float类型在数字后面加一个Fdouble num6 = 3.13176381;//字符char name='果';//布尔值:是非boolean flag=true;}
}

引用类型

接口

数组

字节

位(bit):计算机内部数据存储最小的单位

字节(byte):计算机中数据处理的基本单位,习惯用大写B表示

1B=8bit:1字节等于8位

字符:指计算机中使用的字母、数字、字、符号

数据类型扩展以及面试详解

public class javatest {public static void main(String[] args) {int i=10;int i2=010;//八进制"0"int i3=0x10;//十六进制"0x"//二进制"0b"//=======================================//float 有限 离散 舍入误差 大约 接近但不等于float f=0.1f;double d=1.0/10;System.out.println(f == d);//flase//f和d的输出是一样System.out.println(f);System.out.println(d);float d1=1467899234f;float d2=d1+1;System.out.println(d1==d2);//true//============================//字符拓展//=======================char c1='a';char c2='中';System.out.println((int)c1);//强制转换//所有支付本质是数字//编码 Unicaode表: 2字节char c3='\u0061';System.out.println(c3);//a//转义字符//    \t    制表符//    \n    换行System.out.println("hellow\nworld");//=============================String sa=new String("hello");String sb = new String("hello");System.out.println(sa==sb);//此处输出为false//原因:每一次new都是在申请一个空间,内存地址不一样String sc="hello";String sd="hello";System.out.println(sc=sd);//此处输出为true//对象 从内存分析//布尔值扩展boolean flag=true;if(flag==true){}//新手if(flag){}//老手}
}

类型转换

  • 由于Java是强类型语言,所以要进行有些运算的时候,需要进行有些运算的时候的,需要用到类型转换
//低---------------------高byte,short,char->int->long->float->double
  • 运算中,不同类型的数据先转化为同一数据再运算

  • 强制类型转换(高-》低)

  • 自动类型转换(低-》高)

public class javatest {public static void main(String[] args) {int i = 128;//强制转换   (类型)变量名   高-低//自动转换    低-高byte b=(byte)i;//内存溢出//double b=i; 不会报错/*注意点:1.不能对布尔值进行转换2.不能把对象类型转换为不相干的类型3.在把高容量转为低容量,强制转换4.转换的时候可能会存在溢出,或者精度问题!*/System.out.println((int)23.5);//会导致精度丢失System.out.println("============");char c='a';int d=c+1;//强转数字为dSystem.out.println(d);//输出98System.out.println((char)d);//强转回b}
}

数据越界问题简单解析

public class javatest {    public static void main(String[] args) {        //操作比较大的数的时候,注意溢出问题        //JDK7新特性,数字之间可以用下划线分割(注意jdk版本)        int money=10_0000_0000;        int years=20;        int total1=money*years;//-1474836480,计算时候溢出        long total2=money*years;//默认是int,转换之前可能就出来问题        long total3=money*((long)years);//先把一个数转换为long,则不会越界        System.out.println(total1);        System.out.println(total2);        System.out.println(total3);    }}

变量、常量、作用域

变量

  • 变量是什么?

    就是一个可变的量

  • Java是一种强类型语言,每个变量都必须声明其类型

  • Java变量是程序中最基础的单元,其元素包括变量名,变量类型和作用域

type varName [=value][{,varName[=value]}];
//数据类型 变量名=值;
//可以使用逗号分开来声明多个同类型变量
  • 注意事项:

    每个变量都有类型,类型可以是基本类型,也可以是引用类型

    变量名必须是合法的标识符

    变量声明是一条完整的语句,因此每一个声明都必须以分号结束

public class javatest {//类变量 staticstatic double salary=2500//属性变量//实例变量:从属于对象;如果不自行初始化,这个类型的默认值 0 0.0//布尔值:默认是flase//除了基本类型,其余的默认值都是null;String name;int age;public static void main(String[] args) {//局部变量:必须声明和初始化值int i=10;System.out.println(i);//变量类型  变量名字(随便自己定)=new javatest s=new javatest();//类变量 staticSystem.out.plintln(salary);}//其他方法public void add(){}
}

常量

.初始化后不能再改变的值,不可变动的值

  • 所谓常量可以理解为一种特殊的变量,它的值设定之后,在程序运行过程中不允许被改变

    final 常量名=值;final double PI=3.14;
    
  • 常量名一般使用大写字符

变量命名规范

  • 所有变量、方法、类名:见名知意
  • 类成员变量:首字母小写和驼峰原则:mouthSalary 除了第一个单词以外,后面的单词首字母大写 lastName
  • 局部变量:首字母小写和驼峰原则
  • 常量:大写字母和下划线 MAX_VALUE
  • 类名:首字母大写和驼峰原则:Man,GoodMan
  • 方法名:首字母小写和驼峰原则 run().runRun()

运算符

Java支持的运算符:

  • 算术运算符:+,-,*,/,%,++,–
  • 赋值运算符:=
  • 关系运算符:> ,<, >= ,<= ,== ,!=
  • 逻辑运算符:&&,||,!
  • 位运算符:&,|,^, ~, >>,<<,>>>(了解)
  • 条件运算符:?:
  • 扩展赋值运算符:+=,-=,*=,/=

基本运算符

基础运算

public class javatest {public static void main(String[] args) {int a=10;int b=20;System.out.println(a+b);System.out.println(a-b);System.out.println(a*b);System.out.println(a/b);//算出来为0,默认的是int类型System.out.println(a/(double)b);//输出结果为0.5}
}

类型转换实例

public class javatest {public static void main(String[] args) {long a=1242545362L;int b=10;short c=10;byte d=8;System.out.println(a+b+c+d);//long类型存在的时候结果为longSystem.out.println(b+c+d);//没有long类型默认int;System.out.println(c+d);}
}

关系运算符

public class javatest {public static void main(String[] args) {//关系运算符运行的结果为 true或者flase 布尔值int a=10;int b=20;int c=3;System.out.println(a>b);//long类型存在的时候结果为longSystem.out.println(a<b);//没有long类型默认int;System.out.println(a=b);System.out.println(a%c);//模运算,也就是取余数}
}

自增自减运算符即Math工具类方法

public class javatest {    public static void main(String[] args) {        //++ -- 自增自减 一元运算符       int a=3;       //执行代码后,先给b赋值,再自增       int b=a++;       //执行完代码后,先自增,再给c赋值       int c=++a;               System.out.println(a);        System.out.println(b);        System.out.println(c);                //幂运算 2^3 很多运算需要用到工具类来操作        Math.pow(2,3);    }}

逻辑运算符,位运算符

逻辑运算

public class javatest {    public static void main(String[] args) {     //与 或 非        boolean a=true;        boolean b=false;        //逻辑与运算:两个数都为真,结果才为真        System.out.println("a&&b:" + (a && b));        //逻辑或运算,两个数有一个为真就为真        System.out.println("a||b:" + (a || b));        //如果为真,则为假        System.out.println("!(a&&b:)"+!(a&&b));        //短路运算        int c=5;        boolean d=(c<4)&&(c>3);        System.out.println(d);    }}

位运算

public class javatest {    public static void main(String[] args) {        /*        a=0011 1100        b=0000 1101        ---------------        a&b=0000 1100        a|b=0011 1101        a^b=0011 0001        ~b=1111 0010        << :左移 本质是*2        >> :右移  本质是/2         */        System.out.println(2<<3);//结果为16    }}

三元运算符

public class javatest {    public static void main(String[] args) {        int a=10;        int b=20;        a+=b;//a=a+b;        a-=b;//a=a-b;                //字符串连接符+        System.out.println(""+a+b);//双引号在前面是字符串拼接        System.out.println(a+b+"");//双引号在后面会将前面的运算    }}
public class javatest {    public static void main(String[] args) {      //x?y:z      //如果x==true,则结果y,否则为结果z        int score =50;        String type=score<60 ?"不及格":"及格";        //if        System.out.println(type);    }}

运算符优先级

java 语言中运算符的优先级共分为 14 级,其中 1 级最高,14 级最低

优先级 运算符 结合性
1 ()、[]、{} 从左到右
2 !、+、-、~、++、– 从左到右
3 *、/、% 从左到右
4 +、- 从左到右
5 «、»、>>> 从左到右
6 <、<=、>、>=、instanceof 从左到右
7 ==、!= 从左到右
8 & 从左到右
9 ^ 从左到右
10 | 从左到右
11 && 从左到右
12 || 从左到右
13 ?: 从左到右
14 =、+=、-=、*=、/=、&=、|=、^=、~=、«=、»=、>>>= 从左到右

包机制

  • 为了更好地组织类,java提供了包机制,用于区别类名的命名空间

  • 包语句的语法结构为:

    package pk1[.pk2[.pk3..]];
    
  • 一般来说利用公司域名倒置作为包名

    如:www.baidu.com;建包的时候就是com.baidu.www

  • 为了能够使用某一个包的成员,我们需要在java程序中明确导入包,使用import语句可以完成

    import package1[.package2[.package3]].(classname|*);
    

JavaDoc

  • 用来生成自己的API文档
  • 参数信息
    • @author作者名
    • @version版本号
    • @since指明需要最早使用的jdk版本
    • @param参数名
    • @return返回值情况
    • @throws异常抛出情况
public class javatest {    String name;    /**     *      * @param name     * @return     * @throws Exception     */    public String test(String name) throws Exception{        return name;    }    //学会查找使用idea生产javaDoc文档!    //基础部分的一切知识,后面每天都会用到}
  1. 找到创建的class类的目录,在此目录下打开cmd运行命令 Javados 参数 xxx.java

  2. 会在当前目录下生成一个index.html文件也就是首页,打开就会发现一些简单的东西

Java流程控制

用户交互Scanner

Scanner对象

  • 我们首先知道以前的基本语法没有实现程序和人的交互,但是Java.util.Scanner是Java5新特性,我们可以通过Scanner类来获取用户的输入

    Scanner s=new Scanner(System.in)
    
  • 通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据

    import java.util.Scanner;public class javatest {    public static void main(String[] args) {        //创建一个扫描器对象,用于接收键盘数据        Scanner scanner = new Scanner(System.in);        System.out.println("使用next方式接收");        //判断用户有没有输入字符串        if (scanner.hasNext()) {            //使用next方式接收            String str = scanner.next();            System.out.println("输出内容为:" + str);        }        //凡是属于IO流的类如果不关闭会一直占用资源,要养成良好习惯用完关掉        scanner.close();    }}
    
  • next():

    • 一定要读取有效字符后才可以结束输入
    • 对输入有效字符之前遇到的空白,next()方法会自动将其去掉
    • 只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符
    • next()不能得到带有空格的字符串
    package com.company;import java.util.Scanner;public class Main {    public static void main(String[] args) {        //创建一个扫描器对象,用于接收键盘数据        Scanner scanner = new Scanner(System.in);        System.out.println("使用nextLine方式接收");        //判断用户有没有输入字符串        if (scanner.hasNextLine()) {            //使用next方式接收            String str = scanner.nextLine();            System.out.println("输出内容为:" + str);        }        scanner.close();    }}
    
  • nextLine():

    • 以Enter为结束符,也就是说nextLint()方法返回的是输入回车之前的所有字符
    • 可以获得空白

Scanner进阶使用

package com.company;import java.util.Scanner;public class Main {    public static void main(String[] args) {        Scanner scanner=new Scanner(System.in);        int i;        float f;        System.out.println("请输入整数:");        if(scanner.hasNextInt()){            i=scanner.nextInt();            System.out.println("输出整数为:"+i);        }else        {            System.out.println("输出不为整数!");        }        System.out.println("请输入小数:");        if(scanner.hasNextFloat()){            f=scanner.nextFloat();            System.out.println("输出小数为:"+f);        }else        {            System.out.println("输出不为小数!");        }        scanner.close();    }}

举一个例子

package com.company;import java.util.Scanner;public class Main {    public static void main(String[] args) {        //我们可以输入多个数字,并求其总和与平均值,每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果;        Scanner scanner=new Scanner(System.in);        double sum=0;        int m=0;        //输入除了double类型,直接退出,否则一直执行        while(scanner.hasNextDouble()){            double x=scanner.nextDouble();            m++;            sum=x+sum;            System.out.println(m+"m个数字:"+"所求得的和为sum"+sum);        }        scanner.close();    }}

顺序结构

  • JAVA的基础结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行
  • 顺序结构是最简单的算法结构
  • 语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处理步骤组成的,它是任何一个算法都离不开的一种基本算法结构
package com.company;import java.util.Scanner;public class Main {    public static void main(String[] args) {        System.out.println("1");        System.out.println("2");        System.out.println("3");    }}

选择结构

if单选择结构

package com.company;import java.util.Scanner;public class Main {    public static void main(String[] args) {        Scanner scanner=new Scanner(System.in);        System.out.println("请输入字符串:");        String s = scanner.nextLine();        //equals判断是否相等        if(s.equals("hello")){            System.out.println(s);        }        System.out.println("end");        scanner.close();    }}
  • 语法
if(布尔表达式){    //如果布尔表达式为true}

if双选择结构

package com.company;import java.util.Scanner;public class Main {    public static void main(String[] args) {        Scanner scanner=new Scanner(System.in);        System.out.println("请输入数字:");        int s = scanner.nextInt();        if(s>60){            System.out.println("及格");        }else {            System.out.println("不及格");        }        scanner.close();    }}
  • 语法
if(布尔表达式){    //如果布尔表达式为true}else{    //如果布尔表达式为false}

if多选择结果

package com.company;import java.util.Scanner;public class Main {    public static void main(String[] args) {        Scanner scanner=new Scanner(System.in);        System.out.println("请输入数字:");        int s = scanner.nextInt();        if(s>60&s<=70){            System.out.println("良");        }else if(s>70&s<90){            System.out.println("优");        }else if(s>=90){            System.out.println("强!");        }else{            System.out.println("不及格");        }        scanner.close();    }}
  • 语法
if(布尔表达式1){    //如果布尔表达式1的值为true执行代码}else if(布尔表达式2){    //如果布尔表达式2的值为true执行代码}else if(布尔表达式3){    //如果布尔表达式3的值为true执行代码}else{    //如果以上布尔表达式都不为true执行代码}

嵌套的if结构

package com.company;import java.util.Scanner;public class Main {    public static void main(String[] args) {        Scanner scanner=new Scanner(System.in);        System.out.println("请输入数字:");        int s = scanner.nextInt();        if(s>50){            System.out.println(s);            if(s>90){                System.out.println(s);            }        }        scanner.close();    }}
  • 语法
if(布尔表达式1){    //如果布尔表达式1的值为true执行代码  if(布尔表达式2){    //如果布尔表达式2的值为true执行代码   }}

switch多选择结构

  • switch case 语句判断一个变量与一系列值中某个值是否相等,每个值成为一个分支
  • switch语句中的类型变量可以是
    • byte、short、int、char
    • 从JavaSE7开始
    • switch支持字符串类型
    • 同时case标签必须为字符串常量或字面量
package com.company;public class Main {    public static void main(String[] args) {        String name="kongkong";        switch(name){            case "kongkong":                System.out.println("你好");            case "xiangxiang":                System.out.println("我好");            default:                System.out.println("大家好");        }    }}

输出的结果是”你好我好大家好“,这是因为没有加break语句跳出执行的结果,下面加上可见

public static void main(String[] args) {    String name="kongkong";    switch(name){        case "kongkong":            System.out.println("你好");            break;        case "xiangxiang":            System.out.println("我好");            break;        default:            System.out.println("大家好");            break;    }
  • 语法
switc(expression){    case value:    //语句    break;//可选    case value:    break;    //你可以有任意的case语句    default:}

我们去它的当地目录下查看可以看到反编译文件.class

循环结构

while循环

  • 结构
while(布尔表达式){    //循环内容}
  • 只要布尔表达式为true,就能一直执行下去
  • 大多数情况是会让循环停下来,我们需要一个让表达式失效的方式结束循环
  • 小部分情况需要一直执行,比如服务器的请求响应监听等
  • 循环一直为true会造成无限循环【死循环】,我们需要避免死循环,会影响程序性能或造成程序卡死奔溃
  • 思考1+2+3+4+5+…+100
package com.company;public class Main {    public static void main(String[] args) {       int m=1;       double sum=0;       while(m<=100){           sum+=m;           m++;       }        System.out.println(sum);    }}

do…while循环

  • 对于while而言,如果不满足条件,则不会进入循环。但有的时候我们需要即使不满足条件,也至少执行一次。
  • do…while循环和while循环相似,不同的是,do…while至少会执行一次。
  • 语法
do{    //循环语句}while(布尔表达式);
package com.company;public class Main {    public static void main(String[] args) {       int m=1;       double sum=0;       do{           sum+=m;           m++;       }while (m<=100);        System.out.println(sum);    }}

while和do…while区别

  • while先判断后执行,do…while先执行后判断
  • do…while总是保证循环体会至少被执行一次,这是他们的主要区别
package com.company;public class Main {    public static void main(String[] args) {       int i=0;       while(i<0){           System.out.println(i);//判断失败,退出执行           i++;       }        System.out.println("==========");       do{           System.out.println(i);//先执行再判断,发现失败但已执行       }while(i<0);    }}

for循环

  • for循环语句是支持迭代的一种通用结构,是最有效,最灵活的循环结构

  • for循环执行的次数是在执行前就确定的,语法格式如下

    for(初始化,布尔表达式,更新){//循环语句}
    
    package com.company;public class Main {    public static void main(String[] args) {       int i=0;//初始值       while(i<=100){//条件语句           System.out.println(i);//循环体           i+=2;//迭代           }       //初始值//条件判断//迭代        for (int i1 = 0; i1 < 100; i1++) {            System.out.println(i1);       }        //死循环        for(; ; ){                    }    }}
    
  • 思考

    • 计算0-100之间奇数和偶数的和

    方法一

    package com.company;public class Main {    public static void main(String[] args) {       int sum1=0,sum2=0;        //偶数的相加        for (int i = 0; i <= 100; i=i+2) {            sum1+=i;        }        //奇数的相加        for (int i = 1; i <= 100; i+=2) {            sum2+=i;        }        System.out.println(sum1);        System.out.println(sum2);    }}
    

    方法二

    package com.company;public class Main {    public static void main(String[] args) {       int sum1=0,sum2=0;//通过if-else的判断,在循环的时候就把奇数偶数分离开来        for (int i = 0; i <= 100; i++) {            if(i%2==0){                sum2+=i;//偶数 sum2=sum2+i            }else{                sum1+=i;//奇数            }        }        System.out.println(sum1);        System.out.println(sum2);    }}
    
    • 用while或for循环输出1-1000之间能被5 整除的数,并且每行输出3个

      package com.company;public class Main {    public static void main(String[] args) {        int count=0;        for (int i = 1; i <= 1000; i++) {            if(i%5==0){                System.out.print(i+" ");                count++;            }            if(count%3==0){                System.out.println();            }        }    }}
      
    • 打印九九乘法表

    方法一

    package com.company;public class Main {    public static void main(String[] args) {        int count=0;        for (int i = 1; i <= 9; i++) {//for循环i表示行循环            for (int j = 1; j <=9; j++) {//for循环j表示列循环                if(i>=j)//去重操作                System.out.print(j+"*"+i+"="+i*j+" ");                count++;//加一个计数值便于换行                }            if(count%i==0){                System.out.println();            }        }    }}
    

    方法二

    package com.company;public class Main {    public static void main(String[] args) {        /*        1.我们先打印第一列        2、我们把固定的1再用循环抱起来        3、去掉重复项,i<=j        4、调整样式         */        for (int i = 1; i <= 9; i++) {            for (int j = 1; j<=i; j++) {                System.out.print(j+"*"+i+"="+i*j+"\t");                }                System.out.println();            }        }    }
    
  • 增强for循环

    • 语法
    for(声明语句:表达式){    //代码句子}
    
    • 声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配,其作用域限定在循环语句块,其值与此时数组元素的值相等
    • 表达式:表达式是要访问的数组名,或者是返回值为数组的方法
    package com.company;public class Main {    public static void main(String[] args) {       int[] number={12,123,13,12,42};        for (int i = 0; i < 5; i++) {            System.out.println(number[i]);        }        System.out.println("============");        for(int x :number){            System.out.println(x);        }        }    }
    

break&continue

  • break在任何循环语句的主体部分中,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句(break也能在switch中使用)
package com.company;public class Main {    public static void main(String[] args) {        for (int i = 0; i < 100; i++) {            System.out.println(i);            if(i==30){                break;//执行到30即刻跳出循环            }        }        }    }
  • continue语句用在循环语句中,用于终止某次循环过程,即跳过循环体中,尚未执行的语句,接着进行下一次是否执行循环的判定
package com.company;public class Main {public static void main(String[] args) {for (int i = 0; i < 100; i++) {if(i%10==0){continue;//i=10的倍数的时候在这里跳回循环,没有往下执行}System.out.println(i);}}}
  • goto关键字(了解,不建议使用)
package com.company;public class Main {public static void main(String[] args) {//打印101-150之间的质数int count=0;outer:for (int i = 101; i <150 ; i++) {for (int j = 2; j <i/2 ; j++) {if(i%j==0){continue outer;}}System.out.println(i+" ");}}}

打印三角形

package com.company;public class Main {    public static void main(String[] args) {        //三角形        for (int i = 1; i <= 5; i++) {            for (int j = 5; j >=i; j--) {                System.out.print(" ");            }            for (int j = 1; j <=i; j++) {                System.out.print("*");            }            for(int j=1;j<i;j++){                System.out.print("*");            }            System.out.println();        }    }}

java方法

什么是方法

System.out.println();//类.对象.方法
  • 方法是语句的集合,它们在一起执行一个功能

    • 方法是解决一类问题的步骤的有序组合
    • 方法包含于类或对象中
    • 方法在程序中被创建,在其他地方被引用
  • 设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成一个功能,这样有利于我们后期的扩展
package com.company;public class Main {//main方法    public static void main(String[] args) {        int sum=add(1,3);//调用add方法        System.out.println(sum);        }        //add方法    public static int add(int a,int b){        return a+b;    }}

定义

  • java的方法类似于其他语言的函数,是一段用来完成特殊功能的代码片段,一般情况下,定义一个方法包含以下语法

  • 方法包含一个方法头和一个方法体,下面是方法的所有部分:

    • 修饰符:告诉编译器如何调用该方法,定义了该方法的访问类型
    • 返回值类型:方法可能会返回值。returnVlaueType是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnVlaueType是关键词void
    • 方法名:是方法的实际名称。方法名和参数表共同构成方法签名
    • 参数类型:参数像一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型,顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
      • 形式参数:在方法被调用时用于接收外界的数据
      • 实参:调用方法时实际传给方法的数据
    • 方法体:方法体包含具体的语句,定义该方法的功能。
    修饰符 返回值类型 方法名(参数类型 参数名){    。。。        方法体        。。。        return 返回值;}
    
package com.company;public class Main {    public static void main(String[] args) {        int min = min(21, 124);        System.out.println(min);    }    public static int min(int a,int b){        if (a==b){            System.out.println("两个数相等");            return 0;        }        if(a>b){            return b;        }else {            return a;        }    }}

方法调用

  • 调用方法:对象名.方法名(实参列表)

  • Java支持两种调用方法的方式,根据方法是否返回值来选择

  • 当方法返回一个值的时候,方法调用通常被当作一个值。如

    int m=max(30,28);
    
  • 如果方法返回值为void,方法调用一定是一条语句

    System.out.println("kongkong");
    

值传递(java)和引用传递

值传递

  • 形式参数类型是基本数据类型
  • 方法调用时,实际参数把它的值传递给对应的形式参数
  • 形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元
  • 方法执行中形式参数值的改变不影响实际参数的值

引用传递

  • 形式参数类型是引用数据类型参数,也称为传地址。
  • 方法调用时,实际参数是对象(或数组),这时实际参数与形式参数指向同一个地址
  • 在方法执行中,对形式参数的操作实际上就是对实际参数的操作,这个结果在方法结束后被保留了下来
  • 方法执行中形式参数的改变将会影响实际参数。

进一步理解

Java的方法参数传递只有一种,就是值传递

  • 如果是基本类型,就是将原有的数据拷贝一份,方法内的操作对原有的数据不会有影响。

  • 如果是对象类型,这里是容易误解的地方,因为正好规定对象的地址也叫做"reference", 我们将对象作为参数传递的时候实际上是将对象的地址传递进去。

  • 即使传递的对象,也是传递对象的地址(英文就叫reference了)的值!(值传递!!

方法的重载

  • 重载就是在一个类中,有相同的函数名称,但形参不同的参数
  • 方法的重载规则
    • 方法名必须相同
    • 参数列表必须不同(个数不同,类型不同,参数排序顺序不同)
    • 方法的返回值类型可以相同,可以不同
    • 仅仅返回类型不同不足以成为方法的重载
  • 实现理论:
    • 方法名称相同的时候,编译器会根据调用方法的参数个数,参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错
package com.company;public class Main {    public static void main(String[] args) {        //int min = min(21, 21);        double min=min(21,421);          System.out.println(min);    }    //double min(double a,double b)    public static double min(double a,double b){        if (a==b){            System.out.println("两个数相等");            return 0;        }        if(a>b){            return b;        }else {            return a;        }    }    //int min(int a,int b)    public static int min(int a,int b){        if (a==b){            System.out.println("两个数相等");            return 0;        }        if(a>b){            return b;        }else {            return a;        }    }}

命令行传参

  • 有时候希望你运行一个程序时候再给它传递消息。重要靠传递命令行参数给main()函数实现

    • 编译包的时候:找到目录输入javac xxxx.java
    • 运行包时:回退到src目录下面 输入Java 包路径名 参数

可变参数

  • jdk1.5开始,java支持同类型的可变参数给一个方法
  • 在方法声明中,在指定参数类型后加一个省略号(…)
  • 一个方法只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数都必须在它之前声明
package com.company;public class Main {    public static void main(String[] args) {      printMax(12,41,41,24,52,63);    }    //...自由定义多个变量值    public static void printMax(double... numbers){        if(numbers.length==0){            System.out.println("please put passed");            return;        }        double result=numbers[0];        for (int i = 0; i < numbers.length; i++) {            if(numbers[i]>result){                result=numbers[i];            }        }        System.out.println("the max is "+result);    }}

递归

package com.company;public class Main {    public static void main(String[] args) {        System.out.println(f(4));    }    public static int f(int n){        if(n==1){            return 1;        }else{            return n*f(n-1);        }    }}
  • 能不用递归就不用递归
  • 递归通过栈,调用次数太多,容易导致电脑卡崩

数组

什么是数组

  • 定义

    • 数组是相同类型数据的集合
    • 数组描述的是相同类型的若干个数据,按照一定的先后顺序排序组合而成
    • 其中,每一个数据称作一个数组元素,每个元素可以通过一个下标来访问他们
  • 四个基本特点

    • 长度是确定的。一旦被创建,大小就是不可改变的

    • 元素必须是相同的,不允许是混合类型

    • 元素可以是任何类型,包括基本类型和引用类型

    • 变量属于引用类型,数组也可以看成是对象,每个元素相当于该对象的成员变量

      数组本身就是对象,Java中对象是在堆中的,因此无论保存原始类型还是其他类型,本身是在堆中的

数组声明和创建

  • 首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法

    dataType[] arrary;//首选的方法dataType arrary[];//效果相同,不建议使用
    
  • java语言使用new操作来创建数组,语法

    dataType arrary=new dataType[arrarySize];
    
  • 数组的元素是通过索引访问的,数组索引从0开始。

  • 获取数组长度:arrary.length

  • 数组默认创建值为0

package com.company;public class Main {    public static void main(String[] args) {       int[] sum;//声明一个数组       sum=new int[10];//创建一个数组        //给数组元素中赋值        sum[0]=1;        sum[1]=2;        sum[2]=3;        sum[3]=4;        sum[4]=5;        sum[5]=6;        sum[6]=7;        sum[7]=8;        sum[8]=9;        sum[9]=10;        int result=0;        //获取数组长度:sum.length        for (int i = 0; i <sum.length; i++) {             result =sum[i]+result;        }        System.out.println(result);    }}

内存分析

java内存

    • 存放new的对象和数组
    • 可以被所有的线程分享,不会存放别的对象引用
    • 存放基本变量类型(会包含这个基本类型的具体数值)
    • 引用对象的变量(会存放这个引用在堆里面的具体地址)
  • 方法区
    • 可以被所有的线程共享
    • 包含所有的class和static变量

数组的三种初始化

  • 静态初始化
int[] a={1,2,3}Man[] mans = {new Man(1,1),new Man(2,2)};
  • 动态初始化(手动赋值)
int[] a = new int[2];a[0]=1;a[1]=2;
  • 数组的默认初始化

    • 数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,元素也会被按照实例变量同样方式被隐式初始化
package com.company;public class Main {    public static void main(String[] args) {       //静态初始化:创建+赋值        int[] a={1,2,3,4,5,6,7,8,9};        System.out.println(a[0]);                //动态初始化:包含默认初始化        int[] b=new int[2];        b[1]=2;        System.out.println(b[1]);        System.out.println(b[0]);//没有给b[0]赋值,默认输出值为0    }}

数组边界

  • 下标的合法区间:[0,length-1],如果越界就会报错:

    public static void main(String[] args){   int[] a=new int[2];   System.out.println(a[2]);}
    
  • ArrayIndexOutOfBoundsException:数组下标越界异常!

  • 小结

    • 数组是相同数据类型(数据类型可以为任意类型)的有序集合
    • 数组也是对象。数组元素相当于对象的成员变量
    • 数组长度的确定的,不可变的。如果越界,就会报错

数组使用

首先我们先看传统的数组使用,如下(普通的for循环)

package com.company;public class Main {    public static void main(String[] args) {    int[] a={1,2,3,4,5,6,7,8};    //遍历输出每一个数组元素        for (int i = 0; i <a.length ; i++) {            System.out.println(a[i]);        }        System.out.println("===============");        int sum=0;        //求每一个数组相加和        for (int i = 0; i <a.length ; i++) {           sum+=a[i];        }        System.out.println(sum);        //求最大值        int max=a[0];        for (int i = 0; i <a.length ; i++) {            if(a[i]>max){                max=a[i];            }        }        System.out.println(max);    }}
  • For-Each循环
 //遍历输出每一个数组元素 无下标   for(int b:a){          System.out.println(b);   }
  • 数组作方法入参
 public static void main(String[] args) {    int[] a={1,2,3,4,5,6,7,8};    arrary(a);       }    //打印数组    public static void arrary(int[] a){        for (int i = 0; i <a.length ; i++) {            System.out.println(a[i]);        }    }
  • 数组作返回值
//反转数组public static int[] reverse(int[] a){    int[] result=new int[a.length];    //反转的操作    for (int i = 0,j=result.length-1; i <a.length ; i++,j--) {        result[j]=a[i];    }    return result;}
  • 完整代码
package com.company;public class Main {    public static void main(String[] args) {    int[] a={1,2,3,4,5,6,7,8};    arrary(a);        System.out.println("==========");    //遍历输出每一个数组元素 无下标//        for(int b:a){//            System.out.println(b);//        }        //        arrary(reverse(a));    }    //打印数组    public static void arrary(int[] a){        for (int i = 0; i <a.length ; i++) {            System.out.println(a[i]);        }    }    //反转数组    public static int[] reverse(int[] a){        int[] result=new int[a.length];        //反转的操作        for (int i = 0,j=result.length-1; i <a.length ; i++,j--) {            result[j]=a[i];        }        return result;    }}

多维数组

  • 可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,每一个元素都是一个数组
  • 二维数组
int a[][]=new int[2][5]
  • 解析:以上二维数组a可以看作是一个两行五列的数组
package com.company;public class Main {public static void main(String[] args) {int[][] a={{1,2},{1,4},{1,5}};//打印数组每个元素System.out.println(a[1][1]);System.out.println(a[0][1]);System.out.println(a[1]);//打印的是一个对象,没有输出实际的值arrary(a[0]);System.out.println("=============");//打印数组中每一个元素for (int i = 0; i <a.length ; i++) {for (int j = 0; j <a[i].length ; j++) {System.out.println(a[i][j]);}}//打印数组元素}public static void arrary(int[] a){for (int i = 0; i <a.length ; i++) {System.out.println(a[i]+" ");}}
}

Arrays类

  • 数组的工具类java.util.Arrays

  • 由于数组对象本身没有声明方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些进本操作

  • 查看JDK帮助文档(下载链接)

    参考文章https://blog.csdn.net/qq_40147863/article/details/83051268

  • Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而不用使用对象来调用(是不用不是不能,这点要注意)

  • 常用的功能

    • 给数组赋值:通过fill方法
    • 对数组排序:通过sort方法,按升序
    • 比较数组:通过equals方法比较数组中元素值是否相等
    • 查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作
package com.company;import java.util.Arrays;public class Main {    public static void main(String[] args) {    int[] a={1,25,23452,12,412,63,2};        Arrays.sort(a);//数组排序:升序        //Arrays.toString();打印数组元素        System.out.println(Arrays.toString(a));        Arrays.fill(a,0);//数组填充        //Arrays.fill(a,2,4,0);//在第2到第4的下标中间填充0        System.out.println(Arrays.toString(a));//输出的值都为0    }}

冒泡排序

  • 最出名的排序算法之一,共有8总排序方式
  • 冒泡排序代码还是相当简单的,两层循环,外层冒泡轮数,里层依次比较
  • 我们看到嵌套循环,应该马上就可以得出这个算法的时间复杂度O(n2)。
package com.company;import java.util.Arrays;public class Main {public static void main(String[] args) {int[] a={1,25,23452,12,412,63,2};//sort(a);System.out.println(Arrays.toString(sort(a)));}/*冒泡排序1、比较数组中,两个相邻的元素,交换位置2、每一次比较都会产生一个最大或者最小的数3、下一轮则少一次排序4、依次循环*/public static int[] sort(int[] a) {int temp=0;//外层循环,判断要走几次for (int i = 0; i <a.length-1 ; i++) {//内层循环,比较判断两个数,交换位置for (int j = 0; j <a.length-1-i ; j++) {if (a[j+1]<a[j]){//升序//if (a[j+1]>a[j]){//降序    temp=a[j+1];a[j+1]=a[j];a[j]=temp;}}}return a;}
}

假设已经排好序了,我们就优化一下冒泡

public static int[] sort(int[] a) {        int temp=0;        //外层循环,判断要走几次        for (int i = 0; i <a.length-1 ; i++) {            boolean flag=flase;//通过flag标识位减少没有意义的比较            //内层循环,比较判断两个数,交换位置            for (int j = 0; j <a.length-1-i ; j++) {                if (a[j+1]<a[j]){//升序                //if (a[j+1]>a[j]){//降序                        temp=a[j+1];                    a[j+1]=a[j];                    a[j]=temp;                }            }            if(flag==false){                break;            }        }        return a;}

稀疏数组

引入

  • 需求:五子棋游戏,有存盘退出和续上盘的功能
  • 分析问题:因为该二维数组的很多默认值为0,因此记录很多没有意义的数据
  • 解决:稀疏数组

介绍

  • 当一个数组中大部分元素为0时,或者同一值的数组时,可以用稀疏数组来保存该数组
  • 处理方式
    • 记录数组一共有几行几列
    • 具有不用值的元素和行列值记录在一个小规模的数组中,从而缩小到程序的规模

如下

原始数组

[0 0 0 1 0 2

0 0 3 0 0 0

0 0 0 0 1 0

1 2 0 0 0 0 ]

稀疏数组

[0] 共4 共6 共6
[1] 0 3 1
[2] 0 5 2
[3] 1 2 3
[4] 2 4 1
[5] 3 0 1
[6] 3 1 2
package com.company;import java.util.Arrays;public class Main {public static void main(String[] args) {int[][] a=new int[5][5];a[1][2]=1;a[2][3]=1;System.out.println("输出原始数组");for (int[] ints : a) {for(int ants:ints){System.out.print(ants+" ");}System.out.println();}//转换为稀疏数组//获取有效值个数int sum=0;for (int i = 0; i <5 ; i++) {for (int j = 0; j <5 ; j++) {if(a[i][j]!=0){sum++;}}}System.out.println("有效值个数"+sum);//创建一个稀疏数组的数组int [][] a2=new int[sum+1][3];a2[0][0]=5;a2[0][1]=5;a2[0][2]=sum;//遍历二维数组,并将非零的值,存放到稀疏数组中int count=0;for (int i = 0; i <a.length ; i++) {for (int j = 0; j <a[i].length ; j++) {if(a[i][j]!=0){count++;a2[count][0]=i;a2[count][1]=j;a2[count][2]=a[i][j];}}}//输出稀疏数组System.out.println("稀疏数组");for (int i = 0; i <a2.length ; i++) {System.out.println(a2[i][0]+"\t"+a2[i][1]+"\t"+a2[i][2]+"\t");}System.out.println("==============");System.out.println("还原");//读取稀疏数组int[][] a3=new int[a2[0][0]][a2[0][1]];//给其中的元素还原它的值for (int i = 1; i <a2.length ; i++) {a3[a2[i][0]][a2[i][1]]=a2[i][2];}//打印System.out.println("输出还原数组");for (int[] ints : a3) {for(int ants:ints){System.out.print(ants+" ");}System.out.println();}}
}

面向对象编程

什么是面向对象

  • 面向过程思想

    • 步骤清晰简单,第一部做什么,第二部做什么

    • 面向过程适合处理一些简单的问题

  • 面向对象思想

    • 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对每个分类思考。最后,才会对某个分类下的细节进行面向过程的思索
    • 面向对象适合处理复杂的问题,适合多人协作问题
  • 对于描述复杂的事物,为了宏观上把握从整体上分析,我们需要使用面向对象分析整个系统。但是,具体到微观操作,仍然需要面向过程思路去处理

  • 面向对象编程(Object-Oriented Programming,OOP)

  • 面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据

  • 抽象

  • 三大特征

    • 封装
    • 继承
    • 多态
  • 从认识论角度考虑是现有对象后有类。对象,是具体的事务。类,是抽象的,是对对象的抽象

  • 从代码运行角度考虑是现有类后有对象。类是对象的模板

回顾方法定义和调用

  • 方法的定义

    • 修饰符
    • 返回类型
    • break和return的区别
    • 方法名
    • 参数列表
    • 异常抛出
package com.company;import java.io.IOException;//Main 这就是一个类
public class Main {//main方法public static void main(String[] args) {}/*修饰符 返回值类型 方法名(...){//方法体return 返回值;}*///return 结束方法,返回一个结果public String say(){return "hello";}public void kong(){return;}public int max(int a,int b){return a>b? a:b;}//数组下标越界异常public void readFile(String file)throws IOException{}
}
  • 方法的调用

    • 静态方法

      • student类
      package com.company;public class student {        public static void say() {        System.out.println("hello");            }}
      
      • main调用
      package com.company;public class Main {    public static void main(String[] args) {        student.say();    }}
      
    • 非静态方法

      • student类
      package com.company;public class student {public void say() {System.out.println("hello");}
      }
      
      • main调用
      package com.company;public class Main {public static void main(String[] args) {//实例化这个类//对象类型  对象名=对象值student student=new student();student.say();}
      }
      
    public class Main {public static void main(String[] args) {}//和类一起加载public static void a(){b();//因此这里会报错}//类实例化之后存在public void b(){}
    }
    
    • 形参和实参
    package com.company;public class Main {    public static void main(String[] args) {        //实际参数和形式参数对应        Main main = new Main();//用new来实例化        int a=main.add(1,2);        System.out.println(a);    }    public int add(int a,int b){//非静态方法        return a+b;    }}
    
    • 值传递和引用传递

      • 值传递

        package com.company;public class Main {//值传递    public static void main(String[] args) {        int a=1;        System.out.println(a);        Main.change(a);//调用之后但是无返回值        System.out.println(a);//值为1    }    //返回值为空    public static void change(int a){        a=10;    }}
        
      • 引用传递

        package com.company;public class Main {    public static void main(String[] args) {        Person person = new Person();        System.out.println(person.name);        change(person);        System.out.println(person.name);    }    public static void change(Person person){        //person是一个对象,这是一个具体的人,可以改变属性        person.name="kongkong";    }}//定义一个Person类,有一个属性:nameclass Person{    String name;//name为null}
        
    • this关键字

    package com.company;public class Student {    String name;    int age;    //方法    public void study(){        System.out.println(this.name);    }}
    

类和对象创建

  • 类是一种抽象的数据类型,它是对某一事物整体描述/定义,但是并不是代表某一个具体事物

    • 动物、植物、手机、电脑
    • Person、pet、Car类等,这些类都是用来描述/定义某一类具体事物应该具备的特点和行为
  • 对象是抽象概念的具体实例

    • 张三就是人的一个具体实例,张三家的旺财就是狗的一个具体实例
    • 能够体现特点,展现出功能的是具体的实例,而不是抽象概念
  • 创建与初始化对象

    • 使用new关键字创建
    • 使用new关键字创建的时候,除了分配内存空间外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用
    • 类中的构造器也成为方法,是在进行创建对象的时候必须掌握要调用的,并且构造器有以下两个特点:
      • 必须和类的名字相同
      • 必须没有返回类型,也不能写void
  • Student类

package com.company;public class Student {    String name;    int age;    //方法    public void study(){        System.out.println(this.name);    }}
  • 实例化classMates
package com.company;public class classMates {    //类,抽象的,实例化    //类实例化后会返回抑制自己的对象!    //student对象就是一个Student类的具体实例    public static void main(String[] args) {        Student student = new Student();        student.name="小明";        student.age=12;        System.out.println(student.name);        System.out.println(student.age);    }}

构造器详解(必须掌握)

  • 一个类即使什么都不写,它也有构造方法

  • 构造器

    • 和类名相同
    • 没有返回值
  • 作用

    • 实例化初始值
    • 使用new关键字,必须有构造器,本质在调用构造方法
  • 注意点

    • 定义有参构造后,如果使用无参构造,显示的定义一个无参构造方法
  • Student类

package com.company;public class Student {    //一个类即使什么都不写,都会存在一个方法    //显示的定义构造器    String name;    int age;    //方法    //使用new关键字,本质上在调用构造器    //用来初始化值    public Student(){    }    //有参构造:一旦定义了有参构造,无参构造必须显式定义    public Student(String name){        this.name=name;    }}
  • 实例化
package com.company;public class classMates {    //类,抽象的,实例化    //类实例化后会返回抑制自己的对象!    //student对象就是一个Student类的具体实例    public static void main(String[] args) {        Student student = new Student("kongkong");        System.out.println(student.name);    }}

ALT+INSERT可以直接生成有参无参,或者鼠标右键生成

package com.company;public class Student {//一个类即使什么都不写,都会存在一个方法//显示的定义构造器String name;int age;public String getName() {return name;}public void setName(String name) {this.name = name;}
}}

类和对象小结

package com.company;public class classMates {/*1.类与对象类是一个模板:抽象,对象是一个具体的实例2.方法定义与调用3、对应的引用引用类型:基本类型(8)对象通过引用来操作:栈--->堆4、属性:字段filed 成员变量默认初始化:数字: 0char:u000boolean:false引用:null修饰符  属性类型 属性名=属性值5、对象的创建与使用必须使用new 关键字创造对象 构造器 Person person=new Person();对象的属性 person.name对象的方法 person.sleep6、类静态的属性 属性动态的行为 方法封装、继承、多态*/}
}

封装

  • 该露的露,该藏的藏

    • 我们程序设计追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合就是仅暴露少量的方法给外部使用

    • 封装(数据的隐藏)

      通常,应该禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这就称为信息隐藏

    • 属性私有 get/set

  • Student类

package com.company;//类  private 私有public class Student {    private String name;    private int id;    private char sex;    private  int age;    public String address;    //私有不能直接实例化然后点出来    //提供一些可以操作这个属性的方法    //get 获取这个值    public String getAddress() {        return this.address;    }    //set 给这数据赋值    public void setAddress(String address) {        this.address = address;    }    public String getName() {        return this.name;    }    public void setName(String name) {        this.name = name;    }    public int getId() {        return this.id;    }    public void setId(int id) {        this.id = id;    }    public char getSex() {        return this.sex;    }    public void setSex(char sex) {        this.sex = sex;    }    public int getAge() {        return age;    }//可以写一些方法判断封装    public void setAge(int age) {        if(age>0&&age<120){        this.age = age;        }else {            System.out.println("年龄不合法");        }    }}
  • classMates
package com.company;public class classMates {    /*    1、提高程序的安全性,保护数据    2、隐藏代码的实现细节    3、统一接口    4、系统可维护性增加     */    public static void main(String[] args) {        Student s1 = new Student();        //s1.name  这个是不能调用方法的,因为是私有        s1.setAddress("广东省");        System.out.println(s1.getAddress());//这个是可以调用的        s1.setName("kogkong");        System.out.println(s1.getName());        s1.setAge(110);        System.out.println(s1.getAge());    }}

继承

  • 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模

  • extends的意思是扩展。子类是父类的扩展

  • Java类中只有单继承,没有多继承

  • 继承是类和类之间的一种关系。除此之外还有依赖、组合、聚合

  • 继承关系的两个类,一个为子类(派生类),一个为父类(基类)。子类继承父类,使用关键字extends来表示

  • 子类和父类之间,从某种意义上应该具有“is a”的关系

    • Person类
    package com.company;public class Person {    public void say(){        System.out.println("我能行");    }}
    
    • Student类(继承Person类)
    package com.company;public class Student extends Person{}
    
    • 主函数
    package com.company;public class classMates {    public static void main(String[] args) {        Student s1 = new Student();        //可以看到此时的Student继承了父类的所有方法        s1.say();    }}
    
  • object类

    • 在Java中,所有的类都会默认继承object类
  • super类

    • 注意点

      1. super调用父类的构造方法,必须在构造方法的第一个
      2. super必须只能出现在子类的方法或者构造方法中
      3. super和this不能同时调用构造方法
    • Vs this

      • 代表的对象不同

        this:本身调用这个对象

        super:代表父类对象的调用

      • 前提

        this:没有继承也可以使用

        super:只能在继承条件才能使用

      • 构造方法

        this():本类的构造

        super():父类的构造

  • 方法重写

    • Person类
    package com.company;public class Person {    //重写都是方法的重写,和属性没有关系    public void say(){        System.out.println("我能行");    }}
    
    • Student类(继承Person类)
    package com.company;public class Student extends Person{    @Override//重写方法的注解    public void say() {        System.out.println("加油,别放弃");    }}
    
    • 主函数
    package com.company;public class classMates {    //静态的方法和非静态方法区别很大    //静态方法和定义的数据类型有关    //非静态方法:重写    public static void main(String[] args) {        Student s1 = new Student();        s1.say();        Person s2=new Student();        s2.say();        //结果是一样的        //假设Student类没有重写,s2.say()调用Person里面的东西    }}
    
    • 重写总结

      需要有继承关系,子类重写父类的方法

      1. 方法名必须相同
      2. 参数列表必须相同
      3. 修饰符:范围可以扩大但不能缩小
      4. 抛出的异常:范围,可以被缩小,但不能扩大

      重写,子类的方法和父类必须保持一致:方法体不同

      • 为什么要重写:

        父类的功能,子类不一定需要,也不一定满足

        override重写的注解

多态

  • 即同一个方法可以根据发送对象的不同采取多种不同的行为方式
  • 一个对象的实际类型是确定的,但可以指向对象的引用类型有很多(父类,有关系的类)
  • 多态的存在的条件
    • 有继承关系
    • 子类重写父类方法
    • 父类引用指向子类对象
  • 注意 多态是方法的多态,属性没有多态性
package com.company;
//具体综合继承来思考多态
public class classMates {//一个对象的实力类型是确定的//new Student();//new Person();//可以指向的引用类型就不确定了:父类的引用指向子类//Student 能调用的方法都是自己的或者继承父类的public static void main(String[] args) {Student s1 = new Student();s1.say();//父类型,可以指向子类,但是不能调用子类独有的方法Person s2=new Student();s2.say();//对象能执行那些方法 主要看对象左边的类型,和右边关系不大//子类重写父类的方法,执行子类的方法}
}
  • instanceof和类型转换

(类型转换)引用类型,判断一个对象是什么类型

  1. 父类引用指向子类的对象
  2. 把子类转换为父类,向上转型
  3. 把父类转换为子类,向下转型:强制转换
  4. 方便方法的调用,减少重复的代码!

static

package com.company;//类  private 私有public class Student extends Person{    private static int age;//非静态的变量    private double score;//静态变量    public static void main(String[] args) {        Student s1 = new Student();        System.out.println(s1.age);        System.out.println(s1.score);        System.out.println(Student.age);        //System.out.println(Student.score);//此时这个会报错    }}

静态代码块

package com.company;public class Person {//2 赋初值{System.out.println("匿名代码块");}//1 只执行一次static {System.out.println("静态代码块");}//3public Person(){System.out.println("构造方法");}public static void main(String[] args) {Person s1 = new Person();System.out.println("============");Person s2=new Person();}
}

静态导入包

package com.company;//静态导入包
import static java.lang.Math.random;
import static java.lang.Math.PI;
public class Person {public static void main(String[] args) {System.out.println(random());System.out.println(PI);}}
  • 特别注意

    被Final的类不能被继承

抽象类

  1. abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法就是抽象方法,类就是抽象类
  2. 抽象类中可以没有抽象方法,但是抽象方法一定要有抽象类
  3. 抽象类,不能直接使用new关键字来创建对象,他是用来让子类继承的
  4. 抽象方法,只有方法的声明,没有方法的实现,用来让子类实现
  5. 子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类
  • Person
package com.company;//abstract 抽象类:类extends: 单继承
public abstract class Person {//约束 有人帮我们实现//abstract 抽象方法只有方法名字,没有方法的实现public abstract void doSomething();/*1、不能new这个抽象类,只能靠子类去实现它,约束2、抽象类中可以写普通方法3、抽象方法必须写在抽象类中//抽象的抽象:约束*///思考? new,存在构造器吗//存在的意义:抽象出来提高开发效率
}
  • Student
package com.company;//抽象类的所有方法,继承它的子类,都必须要实现它的方法
//除非子类也是一个抽象类,然后让子子类去写方法
public class Student extends Person{@Overridepublic void doSomething() {}
}

接口

  • 普通类:只有具体实现

  • 抽象类:具体实现和规范(抽象方法)都有

  • 接口:只有规范!自己无法写方法

  • 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则必须能…”的思想。如果你是汽车,你必须能跑。

  • 接口的本质是契约,就像我们人间的法律一样,制定后大家都遵循

  • oo的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如c++,Java)就是因为设计模式所研究的,实际上就是如何合理的去抽象

  • 作用

    • 约束
    • 定义一些方法,让不同的人实现
    • public abstract
    • public static final
    • 接口不能被实例化,接口没有构造器
    • implements可以实现多个接口
    • 必须要重写接口中的方法
  • 事例

    • StudentService
    package com.company;public interface StudentService {String delete(String name);String add(String name);}
    
    • Student
    package com.company;//抽象类:extends
    //类 可以实现接口implements接口
    //实现接口的类,就需要重写接口中的方法//多继承
    public class Student implements StudentService{@Overridepublic String delete(String name) {return null;}@Overridepublic String add(String name) {return null;}
    }
    

内部类

  • 内部类就是在一个类的内部再定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类

    1. 成员内部类

      • student
      package com.company;public class Student {private int id=9;public void out(){System.out.println("这是外部类方法");}public class student1{public void in(){System.out.println("这是内部类方法");}//获取外部类的私有属性public void getID(){System.out.println(id);}}
      }
      
      • 调用方法
      package com.company;public class classMates {public static void main(String[] args) {//外部类通过newStudent student = new Student();//通过这个外部类来实例化内部类Student.student1 student1 = student.new student1();student1.getID();}}
      
    2. 静态内部类

    3. 局部内部类

    public class Student {private int id=9;public void out() {class student1{public void out1(){System.out.println("局部内部类");}}}
    }
    
    1. 匿名内部类
    package com.company;public class Student {public static void main(String[] args) {new apple().eat();//没有名字的初始类,不用实力保存到变量中,节省内存}
    }
    class apple{public void eat(){System.out.println("好吃");}
    }
    

异常

什么是异常

  • 实际工作中,比如说写的某一个模块,用户输入不一定符合你的要求、你的程序要打开某个文件,这个文件可能不存在或者格式不对,你读取数据可能为空,我们的程序再跑着,内存或者硬盘满了
  • 软件程序运行中,遇到的哪些问题就叫做异常,英文Exception。
  • 异常指程序运行中出现的各种状况,如:文件找不到、网络连接失败、非法参数
  • 异常发生再程序运行期间,影响正常执行

分类

  • 检查性异常

    最代表性的检查型异常是用户或问题引起的异常,这是无法预见的

  • 运行时异常

    运行时异常可能是被程序员避免的异常,与检查性异常相反,运行时异常可以再编译时被忽略

  • 错误

    错误不是异常,他是脱离程序员控制的问题,错误代码中通常被忽略。

异常体系结构

  • Java把异常当作对象处理,并定义一个基类java.lang.Throwable作为所有异常的超类

  • 再Java API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常Exception

    • Error

      1. error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关
      2. Java虚拟机运行时报错,当JVM不再有继续执行操作所需的内存资源时,将出现OutOfMemoryError.这些异常发生时,JVM一般选择线程终止
      3. 还有发生在虚拟机试图执行应用时,它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的情况
    • Exception

      1. 在Exception分支中有一个重要的子类

        • RuntimeException(运行时异常)
        • ArrayindexOutOfBoundsException(数组下标越界)
        • NullPointerException(空指针异常)
        • ArithmetcException(算术异常)
        • MissingResourceException(丢失资源)
        • ClassNotFoundException(找不到类)

        这些异常不检查异常,程序中可以捕获处理或者不处理

        通常是程序逻辑引起的,程序员应该从逻辑角度尽可能避免这类异常发生

  • Error和Exception的区别

    Error通常是灾难性的致命错误,是程序无法控制和处理的,出现时,JVM一般选择终止线程;

    Exception通常是可以被程序处理的并且在程序中尽可能的去处理这些异常。

异常处理机制

  • 抛出异常(不处理)
  • 捕获异常(要处理)
package com.company;public class Student {public static void main(String[] args) {int a=1;int b=0;//假设要捕获多个异常:从小到大try{if(b==0){throw new ArithmeticException();//主动抛出异常}System.out.println(a/b);} catch (Error e){//catch 捕获想要的异常类型System.out.println("Error");}catch (Exception e) {System.out.println("Exception");}finally {//处理善后工作System.out.println("finally");}}}
package com.company;public class Student {public static void main(String[] args) {new Student().test(1,0);}
//假设这方法处理不了异常,则可以用这种方式抛出public void test(int a,int b){if(b==0){//throwthrow new ArithmeticException();//主动的抛出异常}}
}
  • 异常处理五个关键字

    • try
    • catch
    • finally
    • throw
    • throws

自定义异常

  • 使用Java内置的异常类可以描述在编程时出现的大部分异常,除此之外,用户还可以自定义异常,用户自定义异常,只需要继承Exception
  • 在程序中使用自定义异常类,大体可以分为以下几个步骤
    • 创建自定义异常
    • 在方法中通过throw关键字抛出异常对象
    • 如果在当前抛出异常的方法中处理异常,可以使用try-catch捕获并处理;否则在方法的声明初通过throws关键字指明要跑出给方法调用者的异常,进行下一步
    • 在出现异常方法的调用这种捕获并处理异常

总结

  • 处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理
  • 在多重catch块后面,加上一个catch(Exception)来处理可能会被遗漏的异常
  • 对于不确定的代码,加上try-catch,处理潜在的异常
  • 切忌只是简单调用printStackTrace()去打印输出
  • 具体如何操作处理异常,要根据不同的业务需求和异常类型去决定
  • 尽量添加finally语句块去释放占用资源

爆肝3万5千字的Java学习笔记(超详细的java)相关推荐

  1. 三万五千字长文!让你懂透编译原理(六)——第六章 属性文法和语法制导翻译

    三万五千字长文!让你懂透编译原理(六)--第六章 属性文法和语法制导翻译 长文预警 系列文章传送门: 万字长文+独家思维导图!让你懂透编译原理(一)--第一章 引论 万字长文!让你懂透编译原理(二)- ...

  2. Pandas教程【国宝级教程,一万八千字总结】

    Pandas教程[国宝级教程,一万八千字总结]

  3. 转发——————《黄金问题3---一万五千字教你如何全面爱护你的膝盖》(正文+1楼回复必看)...

    <黄金问题3---一万五千字教你如何全面爱护你的膝盖>(正文+1楼回复必看)  由 mathiasych 发表在 虎扑篮球· 健身和运动健康 http://bbs.hupu.com/fit ...

  4. 基于Android的漫画阅读器App设计与实现,安卓、MySQL、Java、Andriod Studio,前台用户+后台管理,完美运行,有一万五千字论文。

    基于Android的漫画阅读器App设计与实现,安卓.MySQL.Java.Andriod Studio,前台用户+后台管理,完美运行,有一万五千字论文. 用户模块功能: 引导页:首先进入APP之后会 ...

  5. 千峰HTML5+CSS3学习笔记

    千峰HTML5+CSS3学习笔记 文章目录 千峰HTML5+CSS3学习笔记 写在前面 1. 前言 2. HTML 3. CSS 3.1 选择器 3.2 CSS属性 4. 盒子模型 4.1 溢出属性 ...

  6. 千锋Node.js学习笔记

    千锋Node.js学习笔记 文章目录 千锋Node.js学习笔记 写在前面 1. 认识Node.js 2. NVM 3. NPM 4. NRM 5. NPX 6. 模块/包与CommonJS 7. 常 ...

  7. 3万6千字爆肝,前端进阶不得不了解的函数式编程开发,含大量实例,手写案例,所有案例均可运行

    3w6爆肝,前端进阶不得不了解的函数式编程开发,含大量实例,手写案例,所有案例均可运行 认识函数式编程 函数相关复习 函数是一等公民 高级函数 函数作为参数 案例 1,模拟 forEach 案例 2, ...

  8. 1万七千字精讲,JDK8 的 Lambda、Stream、LocalDate 骚技能

    小Hub领读: 本篇主要讲述是 Java 中 JDK1.8 的一些新语法特性使用,主要是 Lambda.Stream 和 LocalDate 日期的一些使用讲解. 作者:虚无境 来源:cnblogs. ...

  9. 北大才子吴明辉3万5千字的深度分享告诉你:能成功创立秒针跟明略的连环创业者是有秘籍的

    图丨明略数据.秒针系统创始人兼董事长吴明辉 [数据猿导读]千禧年,吴明辉因奥数保送北大,成为2000级数学系的一名学生:2006年创办秒针系统,奠定中国营销监测商业模式:2014年创办明略数据,带队研 ...

最新文章

  1. 带动画效果的卷积神经网络的讲解.pptx
  2. PAT甲级1043 Is It a Binary Search Tree :[C++题解]判断二叉搜索树BST、给定前序序列和中序序列
  3. 【云原生AI】Fluid + JindoFS 助力微博海量小文件模型训练速度提升 18 倍
  4. QT绘制变焦线(Zoom Line)
  5. 单片机原理及其应用——单片机定时器中断实验(八段数码管依次显示0~9数字)
  6. centos 6.7 mysql rpm_CentOS 6.7 下RPM方式安装MySQL 5.6
  7. 在SQL Server2005中使用 .NET程序集
  8. datastage 函数_DataStage常用函数大全
  9. [转]ASP中ActiveX控件的内嵌及调用
  10. android涂鸦板保存功能,android实现涂鸦,保存涂鸦后的图片,清屏
  11. 电脑操作精典密笈60式
  12. 【线程安全】—— 单例类双重检查加锁(double-checked locking)
  13. Codeforces Round #468 (Div. 2): E. Game with String
  14. 25个深度学习开源数据集
  15. Operation not applicable
  16. 阀体端面钻6孔组合机床设计及夹具设计
  17. 20170330今日头条笔试题
  18. 如何求解最大公约数和最小公倍数
  19. 博客广告 何乐而不为?
  20. 手机共享计算机网络连接,如何将手机wifi网络通过USB共享给电脑?教您共享方法...

热门文章

  1. Jmeter学习笔记(八)——监听器元件之聚合报告
  2. 浅析WeakHashMap
  3. 全志F1C200S嵌入式驱动开发(触摸屏驱动)
  4. 【CQF Finance Class 2 货币市场】
  5. vue项目的文字及背景色配置
  6. vue项目打包wap2app项目生成apk保姆级教程适合新手看,建议收藏
  7. 解决微信开发者工具黑屏
  8. 基于vue3,popperjs下拉框简易实现
  9. Neo4j CQL(函数、索引、约束)、备份恢复、优化
  10. 苹果cmsv10视频播放下载2tu风格模板