JavaSE上篇

Java

JavaSE

1.JavaSE:Java入门

1.1 Java的特性和优势

一、简单性

就是c++语法的纯净版。没有头文件,指针运算,结构,联合,操作符重载,虚基类等等。由于语法基于c,因此学习起来完全不费力。

二、面向对象

面向对象是一种程序设计技术,他将重点放在数据(即对象)和对象之间的接口上。模拟人的思维写程序,万物皆对象!

三、可移植性(跨平台性)

这是JAVA的一个重要的优势。JAVA代码或者说字节码、二进制码可以跨平台的移植,而不用管具体的操作系统和硬件环境。 “一次编写,随处运行”:“write once, run anywhere”,JAVA在设计时就很注重移植和跨平台性。比如:JAVA的Int永远都是32位。不像c++可能是16,32,可能是根据编译器厂商规定的变化。这样的话程序的移植就会非常麻烦。

四、高性能

​ JIT(JUST IN TIME)即时编译。将一些“热点”字节码编译成本地机器码,并将结果缓存起来,在需要的时候重新调用。这样的话,使JAVA程序的执行效率大大提高,某些代码甚至接近c++的效率。随着这种技术的一天天完善,也许有一天会超越编译代码的效率。

五、分布式

​ JAVA是为internet的分布式环境设计的,因为他能够处理tcp/ip协议。事实上,通过url访问一个网络资源和访问本地文件是一样简单的。Java还支持远程方法调用(RMI,remote method Invocation),使程序能够通过网络调用方法。

六、动态性

就是在需要时将某些代码添加到正在运行的程序中。反射机制。当需要把某些代码添加到正在运行的程序中时,动态性是一个非常重要的特性。Java的动态特性是其面向对象设计方法的扩展。它允许程序动态地装入运行过程中所需要的类,这是C++语言进行面向对象程序设计所无法实现的

七、多线程

多线程的使用可以带来更好的交互响应和实时行为。多线程的简单性是Java成为主流服务器端开发语言的主要原因之一。

八、安全性

​ Java适合于网络/分布式环境,为了达到这个目标,在安全性方面投入了很大的精力,使Java可以构建防病毒,防篡改的系统。

九、健壮性

​ Java是一种健壮的语言,吸收了C/C++ 语言的优点,但去掉了其影响程序健壮性的部分(如:指针、内存的申请与释放等)。Java程序不可能造成计算机崩溃。Java系统仔细检测对内存的每次访问,确认它是合法的,而且不致引起任何问题。不过,即使Java程序也可能有错误。如果出现某种出乎意料之事,程序也不会崩溃,而是把该例外抛弃。再通过异常处理机制,程序就会发现这类例外,并加以处理。

1.2 JDK和JRE

JDK

Java 2 SDK (Development Kit)包含:JRE的超集,包含编译器和调试器等用于程序开发的文件

JRE

Java Runtime Environment (JRE) 包含:Java虚拟机、库函数、运行Java应用程序和Applet所必须文件

区别和联系

JDK是JRE的超集,是在jre的基础上增加了编译器及其他一些开发工具。jre就是java运行时环境,包括了jvm和其它一些java核心api,任何一台电脑,只有安装了jre才可以运行java程序。如果只是要运行JAVA程序,之需要JRE就可以。 JRE通常非常小,也包含了JVM。

1.3 初识JVM

JVM是一种规范,可以使用软件来实现,也可以使用硬件来实现,就是一个虚拟的用于执行bytecodes字节码的计算机。他也定义了指令集、寄存器集、结构栈、垃圾收集堆、内存区域。 JVM负责将java字节码解释运行,边解释边运行,这样,速度就会受到一定的影响。JAVA提供了另一种解释运行的方法JIT(just in time),可以一次解释完,再运行特定平台上的机器码,高级的JIT可以只能分析热点代码,并将这些代码转成本地机器码,并将结果缓存起来,下次直接从内存中调用,这样就大大提高了执行JAVA代码的效率。这样就实现了跨平台、可移植的功能。

1.4 Java开发环境搭建
  1. 选择版本

  2. 同意协议

  3. 查看电脑的环境

  4. 下载安装包

  5. 安装JDK与JRE

  6. 配置电脑的环境变量 :

​ 6.1我的电脑–>右键—>属性

​ 6.2环境变量–>添加 JAVA_HOME

​ 6.3配置path:%JAVA_HOME%bin ;%JAVA_HOME%jrebin

  1. 测试是否安装成功:

​ 7.1打开cmd(命令行窗口)

​ 7.2输出 java –version 查看版本信息,是否成功输出!

1.5 JAVA程序运行机制

第一步:编译

​ 利用编译器(javac)将源程序编译成字节码à 字节码文件名:源文件名.class

第二部:运行

​ 利用虚拟机(解释器,java)解释执行class字节码文件

1.6 Java内存分析

一、栈 stack

  1. 每个线程私有,不能实现线程间的共享

  2. 局部变量放置于栈中

  3. 栈是由系统自动分配,速度快栈是一个连续的内存空间

二、堆heap

  1. 放置new出来的对象

  2. 堆是一个不连续的内存空间,分配灵活,速度慢

三、方法区(也是堆)

  1. 被所有线程共享

  2. 用来存放程序中永远是不变或唯一的内容(类代码信息、静态变量、字符串常量)

2.JavaSE:基础语法

2.1 标识符
2.1.1 注意事项

1.所有的标识符都应该以字母(A-Z 或者 a-z),美元符($)、或者下划线(_)开始

2.首字符之后可以是字母(A-Z 或者 a-z),美元符($)、下划线(_)或数字的任何字符组合

​ 3.不能使用关键字作为变量名或方法名

​ 4.标识符是大小写敏感的

​ 5.合法标识符举例:age、$salary、_value、__1_value

​ 6.非法标识符举例:123abc、-salary、#abc

2.2.2 命名规则

​ 1.表示类名的标识符用大写字母开始

如: class Man, class GoodMan 

​ 2.表示方法和变量的标识符用小写字母开始,后面的描述性词以大写开始。

如: eat(),eatFood()
//驼峰命名法
2.2 注释

Java中的注释有三种:

1.单行注释:只能注释当前行,以//开始,直到行结束

//输出HelloWorld!

2.多行注释:注释一段文字,以/开始, /结束!

/*
这是我们Java程序的主入口,
main方法也是程序的主线程。
*/

3.文档注释:用于生产API文档,配合JavaDoc

/*
* @Description HelloWor类
* @Author GuoJingPeng
**/
2.3 数据类型
2.3.1 强弱类型语言

强类型语言:

Java是一种强类型语言,每个变量都必须声明其类型。强类型语言也称为强类型定义语言。要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用。Java、.NET、C++等都是强制类型定义的。也就是说,一旦一个变量被指定了某个数据类型,如果不经过转换,那么它就永远是这个数据类型了。安全性高,运行效率相对较慢,鱼和熊掌不可兼得!强类型定义语言在速度上可能略逊色于弱类型定义语言,但是强类型定义语言带来的严谨性能够有效的避免许多错误。与其相对应的是弱类型语言。

弱类型语言:

弱类型语言也称为弱类型定义语言。与强类型定义相反。像vb,php等就属于弱类型语言·在VBScript中,可以将字符串‘12’和整数3进行连接得到字符串‘123’,也可以把它看成整数123,而不需要显示转换。是不是十分的随便,我们Java就不是这样的。但其实它们的类型没有改变,VB只是在判断出一个表达式含有不同类型的变量之后,自动在这些变量前加了一个clong()或(int)()这样的转换函数而已。能做到这一点其实是归功于VB的编译器的智能化而已,这并非是VB语言本身的长处或短处。

2.3.2 数据类型

Java的数据类型分为两大类:基本类型和引用类型

一、基本类型:数值类型包括(整数类型(byte(占一位)、int(占四位)、short(占两位)、long(占八位))、浮点类型(double(占八位)、float(占四位))、字符类型(char占两位))、bolean类型(占一位,只有false和true)

二、引用类型:类、接口、数组

三、Java语言的整型常数默认为int型,浮点数默认是Double

public static void main(String[] args) {
    //整型
    int i1=100;
    //长整型
    long i2=998877665544332211L;
    //短整型
    short i3=235;
    //浮点型
    double d1=3.5; //双精度
    double d2=3;
    float f1=(float)3.5; //单精度
    float f2=3.5f; //单精度
    //布尔类型 boolean true真/false假
    boolean isPass=true;
    boolean isOk=false;
    boolean isBig=5>8;
if(isPass){
    System.out.println("通过了");
}else{
    System.out.println("未通过");
}
    //单字符
    char f='女';
    char m='男';
}
2.3.3 整型拓展

十进制整数,如:99, -500, 0

八进制整数,要求以 0 开头,如:015

十六进制数,要求 0x 或 0X 开头,如:0x15

int i=10;
int i2=010;
int i3=0x10;
System.out.println(i); //10
System.out.println(i2); //8
System.out.println(i3); //16
2.3.4 浮点型拓展
//浮点类型flfloat, double的数据不适合在不容许舍入误差的金融计算领域。如果需要进行不产生舍入误差的精确数字计算,需要使用BigDecimal类
public static void main(String[] args) {
   float f = 0.1f;
   double d = 1.0/10;
   System.out.println(f==d); //false
   float d1 = 2131231231f;
   float d2 = d1+1;
if(d1==d2){
   System.out.println("d1==d2");
}else{
   System.out.println("d1!=d2");
  }
}
/*该工具类提供的方法
加法:add
减法:subtract
除法:divide
乘法:multiply
*/
public static void main(String[] args){
   BigDecimal bigDecimal1= BigDecimal.valueof(0.72);
   BigDecimal bigDecimal2= BigDecimal.valueof(0.48);
 return bigDecimal1.add(bigDecimal2).doubleValue(); 
}

一、原因:

由于字长有限,浮点数能够精确表示的数是有限的,因而也是离散的。浮点数一般都存在舍入误差,很多数字无法精确表示,其结果只能是接近,但不等于;二进制浮点数不能精确的表示0.1,0.01,0.001这样10的负次幂。并不是所有的小数都能可以精确的用二进制浮点数表示。

二、浮点数使用总结:

  1. 默认是double

  2. 浮点数存在舍入误差,很多数字不能精确表示。如果需要进行不产生舍入误差的精确数字计算,需要使用BigDecimal类。

  3. 避免比较中使用浮点数

  4. Java.math下面的两个有用的类:BigInteger和BigDecimal,这两个类可以处理任意长度的数值。BigInteger实现了任意精度的整数运算。BigDecimal实现了任意精度的浮点运算。

2.3.5 字符型拓展

单引号用来表示字符常量。例如‘A’是一个字符,它与“A”是不同的,“A”表示一个字符串。

//将字符强转为int
public static void main(String[] args) {
   char c1 = 'a';
   char c2 = '中';
   char c3 = '\u0061';
   System.out.println(c1);
   System.out.println((int) c1); //97
   System.out.println(c2);
   System.out.println((int) c2); //20013
   System.out.println(c3); //a
}
2.3.6 布尔型拓展

1.boolean类型有两个值,true和false,不可以 0 或非 0 的整数替代true 和 false,这点和C语言不同。

  1. boolean 类型用来判断逻辑条件,一般用于程序流程控制。
  2. boolean类型(一位,不是一个字节),就是0|1
//很多新手程序员喜欢这样写
if (is == true && un == false ) {...}
//对于一个熟练的人来说,应该用如下方式来表示:
if ( is && !un ) {....}
2.3.7 类型转换

​ 1.整型、实型(常量)、字符型数据可以混合运算

​ 2.运算中,不同类型的数据先转化为同一类型,然后进行运算

​ 3.转换从低级到高级(根据容量来看)

//低 ------------------------------------> 高
byte,short,char> int> long> float> double

注意数据类型转换必须满足如下规则:

1.不能对boolean类型进行类型转换。

2.不能把对象类型转换成不相关类的对象。

3.在把容量大的类型转换为容量小的类型时必须使用强制类型转换。转换过程中可能导致溢出或损失精度,例如:

//因为byte类型8位,最大值为127,所以当 int 强制转换为byte类型时,值128就会导致溢出
int i =128;
byte b = (byte)i;

4.浮点数到整数的转换是通过舍弃小数得到,而不是四舍五入,例如:

(int)23.7 == 23;
(int)-45.89f == -45
2.3.7.1 自动类型转换

自动类型转换:容量小的数据类型可以自动转换为容量大的数据类型

解析:c1 的值为字符 a ,查 ASCII 码表可知对应的 int 类型值为 97, A 对应值为 65,所以i2=65+1=66

/*short数据类型的位数为16位,就可以自动转换位数为32的int类型,同样float数据类型的位数为32,可以自动转换为64位的double类型*/
public class ZiDongLeiZhuan{
public static void main(String[] args){
   char c1='a';//定义一个char类型
   int i1 = c1;//char自动类型转换为int
   System.out.println("char自动类型转换为int后的值等      于"+i1);
   char c2 = 'A';//定义一个char类型
   int i2 = c2+1;//char 类型和 int 类型计算
   System.out.println("char类型和int计算后的值等于"+i2);
   }
}
2.3.7.2 强制类型转换

1.强制类型转换,又被称为造型,用于显式的转换一个数值类型

2.在有可能丢失信息的情况下进行的转换是通过造型来完成的,但 可能造成精度降低或溢出。

  1. 条件是转换的数据类型必须是兼容的
  2. 当将一种类型强制转换成另一种类型,而又超出了目标类型的表示范围,就会被截断成为一个完全不同的值,称为溢出
public static void main(String[] args) {
   double x = 3.14;
   int nx = (int)x; //值为3
   char c = 'a';
   int d = c+1;
   int x = 300;
   System.out.println(d); //98
   System.out.println((char)d); //b    
   byte bx = (byte)x; //值为44
   System.out.println(bx);
}
2.3.7.3 常见错误问题

1.操作比较大的数时,要留意是否溢出,尤其是整数操作时

public static void main(String[] args) {
   int money = 1000000000; //10亿
   int years = 20;
   int total = money*years; //返回的是负数
   long total1 = money*years; //返回的仍然是负数。默认是int,因此结果会转成int值,再转成long但是已经发生了数据丢失
   long total2 = money*((long)years); //先将一个因子变成  long,整个表达式发生提升全部用long来计算。
   System.out.println(total);
   System.out.println(total1);
   System.out.println(total2);
}
  1. L和l 的问题

    //不要命名名字为l的变量
    //long类型使用大写L不要用小写
    public static void main(String[] args) {
       int l = 2;
       long a = 23451l;
       System.out.println(l+1); //3
       System.out.println(a); //23451
    }
    
2.4 JDK7新特性扩展

1.二进制整数

//0b开头即可
int a = 0b0101;//5

2.下划线分隔符

int b = 1_2234_5678;//1亿2234万5678
2.5 变量
2.5.1 变量的定义

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

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

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

int a, b, c; // 声明三个int型整数:a、 b、c
int d = 3, e = 4, f = 5; // 声明三个整数并赋予初值
byte z = 22; // 声明并初始化z
String s = "runoob"; // 声明并初始化字符串s
double pi = 3.14159; // 声明了双精度浮点型变量pi
char x = 'x'; // 声明变量x的值是字符'x'
2.5.2 变量作用域

变量根据作用域可划分为三种:

1.类变量(静态变量):独立于方法之外的变量,用 static 修饰。

2.实例变量(成员变量):独立于方法之外的变量,不过没有 static 修饰。

3.局部变量:类的方法中的变量。

public class Variable{
   static int allClicks=0; // 类变量
   String str="hello world"; // 实例变量
   public void method(){
   int i =0; // 局部变量
 }
}
2.5.3 局部变量

1.方法或语句块内部定义的变量

2.生命周期是从声明位置开始到”}”为止

3.在使用前必须先声明和初始化

4.局部变量没有默认值,所以局部变量被声明后,必须经过初始化,才可以使用

public static void main(String[] args) {
   int i;
   int j = i+5 ; // 编译出错,变量i还未被初始化
   System.out.println(j);
   //修改为
   int i=10;
   int j = i+5 ;
   System.out.println(j);
}
2.5.4 实例变量

1.方法外部、类的内部定义的变量

2.从属于对象,生命周期伴随对象始终

3.如果不自行初始化,他会自动初始化成该类型的默认初始值

4.数值型变量初始化成0或0.0,字符型变量的初始化值是16位的0,布尔型默认是false

public class Test {
   // 这个实例变量对子类可见
   public String name;
   // 私有变量,仅在该类可见
   private double salary;
}
2.5.5 静态变量

1.使用static定义。

2.从属于类,生命周期伴随类始终,从类加载到卸载

3.如果不自行初始化,他会自动初始化成该类型的默认初始值

4.数值型变量初始化成0或0.0,字符型变量的初始化值是16位的0,布尔型默认是false

public class Employee {
   //salary是静态的私有变量
   private static double salary;
   // DEPARTMENT是一个常量
   public static final String DEPARTMENT = "开发人员";
   public static void main(String[] args){
   salary = 10000;
   System.out.println(DEPARTMENT+"平均工资:"+salary);
   }
}   
2.6常量

一、常量名一般使用大写字符

二、常量(Constant):初始化(initialize)后不能再改变值!不会变动的值。

final 常量名=;
final double PI=3.14; final String LOVE="hello";

​ 三、命名规范:

1.所有变量、方法、类名:见名知意

  1. 类成员变量:首字母小写和驼峰原则 : monthSalary

  2. 局部变量:首字母小写和驼峰原则

  3. 常量:大写字母和下划线:MAX_VALUE

  4. 类名:首字母大写和驼峰原则: Man, GoodMan

  5. 方法名:首字母小写和驼峰原则: run(), runRun()

2.7 运算符

Java 语言支持如下运算符:

1.算术运算符: +,-,*,/,%,++,–

2.赋值运算符 =

3.关系运算符: >,<,>=,<=,==,!= instanceof

4.逻辑运算符: &&,||,!

5.位运算符: &,|,^,~ , >>,<<,>>> (了解!!!)

6.条件运算符 ?:

7.扩展赋值运算符:+=,-=,*=,/=

2.7.1 二元运算符
//两个操作数
public static void main(String[] args) {
   int a = 10;
   int b = 20;
   int c = 25;
   int d = 25;
   System.out.println("a + b = " + (a + b) );
   System.out.println("a - b = " + (a - b) );
   System.out.println("a * b = " + (a * b) );
   System.out.println("b / a = " + (b / a) );
}   
2.7.2 整数运算

1.如果两个操作数有一个为Long, 则结果也为long

2.没有long时,结果为int。即使操作数全为shot,byte,结果也是int

public static void main(String[] args) {
   long a = 1231321311231231L;
   int b = 1213;
   short c = 10;
   byte d = 8;
   System.out.println((a+b+c+d)); //Long类型
   System.out.println((b + c + d));//Int类型
   System.out.println((c + d));//Int类型
}
2.7.3 浮点运算

1.如果两个操作数有一个为double, 则结果为double.

2.只有两个操作数都是flfloat, 则结果才为float.

public static void main(String[] args) {
   float a = 3.14565F;
   double b = 3.194546464;
   float c = 1.3123123F;
   System.out.println(a+b); //double类型
   System.out.println(b+c); //double类型
   System.out.println(a+c); //float类型
}
2.7.4 关系运算符
==检查两个数的值是否相等,相等返回真
!=检查两个数的值是否相等,不相等返回真
>检查左边的数是否大于右边的数,大于返回真
<检查左边的数是否小于右边的数,小于返回真
>=检查左边的数是否大于等于右边的数,大于或等于返回真
<=检查左边的数是否小于等于右边的数,小于或等于返回真
2.7.5 取模运算

1.负数%负数=负数;

2.负数%正数=负数;

3.正数%负数=正数;

//一般都是正整数运算,进行结果的判断
public static void main(String[] args) {
   System.out.println(9 % 4); //1
   System.out.println(-9 % -4); //-1
   System.out.println(-10 % 4); //-2
   System.out.println(9 % -4); //1
}   
2.7.6 一元运算符

​ 1.自增(++)自减(–)运算符是一种特殊的算术运算符

​ 2.在算术运算符中需要两个操作数来进行运算

​ 3.自增自减运算符是一个操作数,分为前缀和后缀两种

public static void main(String[] args) {
   int a = 3;
   int b = a++; //执行完后,b=3。先给b赋值,再自增。
   int c = ++a; //执行完后,c=5。先自增,再给b赋值
}
2.7.7 逻辑运算符

1.逻辑与:&&和&

2.逻辑或:||和|

3.逻辑非:!

&&当两个操作数都为真,结果为真
||当两个操作数任何一个为真,则结果为真
用来反转操作数逻辑状态,如果条件为true,结果为flase
2.7.8 位运算符

Java定义了位运算符,应用于整数类型(int),长整型(long),短整型(short),字符型(char),和字节型 (byte)等类型。位运算符作用在所有的位上,并且按位运算

A = 0011 1100
B = 0000 1101
-----------------
A&b = 0000 1100
A | B = 0011 1101
A ^ B = 0011 0001
~A= 1100 0011

2.7.9 扩展运算符
public static void main(String[] args) {
    int a=10;
    int b=20;
    a+=b; // a = a + b
    a-=b; // a = a - b
    a*=b; // a = a * b
    a/=b; // a = a / b 
    System.out.println(a+":"+b);
}
2.7.10 字符串连接符

“+” 运算符两侧的操作数中只要有一个是字符串(String)类型,系统会自动将另一个操作数转换为字符串 然后再进行连接。

//字符串
String s1="Hello 中文!";
String s2=1+""; //转换成String
//int
int c = 12;
System.out.println("c=" + c);

2.7.11 三目条件运算符

三目条件运算符,语法格式:

其中x为boolean类型表达式,先计算x的值,若为true,则整个三目运算的结果为表达式y的值,否则整个运算结果为表达式z的值。

x ? y : z
public static void main(String[] args) {
   int score = 80;
   String type = score < 60 ? "不及格" : "及格";
   System.out.println("type= " + type);//及格
}

2.8 包机制

import 关键字

1.如果两个类重名,需要导入对应的包,否则就需要写出完整地址:

com..dao.Hello hello = new com.kuang.dao.Hello()

2.用 import 关键字引入,使用通配符 “*” , 导入io包下的所有类!

import java.io.*;
//不建议这样使用,因为会全局扫描,影响速度!

3.使用 import 关键字引入指定类:

import com.kuang.Hello;
2.9 JavaDoc

1.JavaDoc是一种将注释生成HTML文档的技术,生成的HTML文档类似于Java的API,易读且清晰明了

2.使用方式:使用命令行在目标文件所在目录输入javadoc +文件名.java

public class HelloWorld {
public String name;
   /**
   * @param name 姓名
   * @return 返回name姓名
* @throws Exception 无异常抛出
   **/
public String function(String name) throws Exception{
  return name;
}
/* 开始,以 / 结束。
@author 作者名
@version 版本号
@since 指明需要最早使用的jdk版本
@param 参数名
@return 返回值情况
@throws 异常抛出情况

3.命令行生成Doc

-encoding UTF-8 -charset UTF-8
//解决GBK乱码问题,在中间添加编码设置

3.JavaSE:流程控制

3.1 用户交互
3.1.1 Scanner

java.util.Scanner 是 Java5 的新特征,我们可以通过 Scanner 类来获取用户的输入。

下面是创建 Scanner 对象的基本语法:

Scanner s = new Scanner(System.in);
3.1.2 next & nextLine

通过 Scanner 类的 next() 与 nextLine() 方法获取输入的字符 串,在读取前我们一般需要 使用 hasNext() 与 hasNextLine() 判断是否还有输入的数据。

​ 如果要输入 int 或 float 类型的数据,在 Scanner 类中也有支持,但是在输入之前最好先使用 hasNextXxx() 方法进行验证,再使用 nextXxx() 来读取。

1.我们使用next方式接收一下输入的数据:

public static void main(String[] args) {
   //创建一个扫描器对象,用于接收键盘数据
   Scanner scanner = new Scanner(System.in);
   //next方式接收字符串
   System.out.println("Next方式接收:");
   //判断用户还有没有输入字符
   if (scanner.hasNext()){
String str = scanner.next();
   System.out.println("输入内容:"+str);
   }
   /*凡是属于IO流的类如果不关闭会一直占用资源.要养成好习惯用完就关掉.就好像你接水完了要关水龙头一样.很多下载软件或者视频软件如果你不彻底关,都会自己上传下载从而占用资源,你就会觉得卡,这一个道理 */
   scanner.close();
}
//测试数据:Hello World!
//结果:输出了Hello

2.使用nextLine()来接收数据:

public static void main(String[] args) {
   Scanner scan = new Scanner(System.in);
   // 从键盘接收数据
   // nextLine方式接收字符串
   System.out.println("nextLine方式接收:");
   // 判断是否还有输入
   if (scan.hasNextLine()) {
   String str2 = scan.nextLine();
   System.out.println("输入内容:" + str2);
   }
   scan.close();
 }
//测试数据:Hello World!
//结果:输出了Hello World!

3.两者区别:

一、next():

1.一定要读取到有效字符后才可以结束输入。

2.对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。

3.只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。

4.next() 不能得到带有空格的字符串。

二、nextLine():

1.以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符

​ 2.可以获得空白。

3.2 顺序结构

JAVA的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行。

public static void main(String[] args) {
   System.out.println("Hello1");
   System.out.println("Hello2");
   System.out.println("Hello3");
   System.out.println("Hello4");
   System.out.println("Hello5");
}
//按照自上而下的顺序执行!依次输出。
3.3 选择结构
3.3.1 if单选择结构
if(布尔表达式){
//如果布尔表达式为true将执行的语句
}
//比如我们来接收一个用户输入,判断输入的是否为Hello字符串:
public static void main(String[] args) {
   Scanner scanner = new Scanner(System.in);
   //接收用户输入
   System.out.print("请输入内容:");
   String s = scanner.nextLine();
if (s.equals("Hello")){
   System.out.println("输入的是:"+s);}
    }
   System.out.println("End");
   scanner.close();
}
3.3.2 if双选择结构
if(布尔表达式){
//如果布尔表达式的值为true
}else{
//如果布尔表达式的值为false
}
//考试分数大于60就是及格,小于60分就不及格
public static void main(String[] args) {
   Scanner scanner = new Scanner(System.in);
   System.out.print("请输入成绩:");
   int score = scanner.nextInt();
if (score>60){
   System.out.println("及格");
}else {
   System.out.println("不及格");
}
   scanner.close();
}
3.3.3 if多选择结构

使用 if,else if,else 语句的时候,需要注意下面几点:

​ 1.if 语句至多有 1 个 else 语句,else 语句在所有的 else if 语句之后

​ 2.if 语句可以有若干个 else if 语句,它们必须在 else 语句之前。

​ 3.一旦其中一个 else if 语句检测为 true,其他的 else if 以及 else 语句都将跳过执行

if(布尔表达式 1){
//如果布尔表达式 1的值为true执行代码
}else if(布尔表达式 2){
//如果布尔表达式 2的值为true执行代码
}else if(布尔表达式 3){
//如果布尔表达式 3的值为true执行代码
}else {
//如果以上布尔表达式都不为true执行代码
}
//学校根据分数区间分为ABCD四个等级
public static void main(String[] args) {
   Scanner scanner = new Scanner(System.in);
   System.out.print("请输入成绩:");
   int score = scanner.nextInt();
if (score==100){
   System.out.println("恭喜满分");
}else if (score<100 && score >=90){
   System.out.println("A级");
}else if (score<90 && score >=80){
   System.out.println("B级");
}else if (score<80 && score >=70){
   System.out.println("C级");
}else if (score<70 && score >=60){
   System.out.println("D级");
}else if (score<60 && score >=0){
   System.out.println("不及格!");
}else {
   System.out.println("成绩输入不合法!");
}
   scanner.close();
}   
3.3.4 嵌套的if结构
if(布尔表达式 1){
//如果布尔表达式 1的值为true执行代码
if(布尔表达式 2){
//如果布尔表达式 2的值为true执行代码
 }
}
3.3.5 switch多选择结构

switch case语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支

switch(expression){
    case value :
    //语句      
    break; //可选
    case value :
    //语句
    break; //可选
    //你可以有任意数量的case语句
    default : //可选
    //语句
}

switch case 语句有如下规则:

1.switch 语句中的变量类型可以是: byte、short、int 或者 char。从 Java SE7 开始,switch 支持字符串 String 类型了,同时 case 标签必须为字符串常量或字面量

2.switch 语句可以拥有多个 case 语句。每个 case 后面跟一个要比较的值和冒号

3.case 语句中的值的数据类型必须与变量的数据类型相同,而且只能是常量或者字面常量

4.当变量的值与 case 语句的值相等时,那么 case 语句之后的语句开始执行,直到 break 语句出现 才会跳出 switch 语句

5.当遇到 break 语句时,switch 语句终止。程序跳转到 switch 语句后面的语句执行。case 语句不必 须要包含 break 语句。如果没有 break 语句出现,程序会继续执行下一条 case 语句,直到出现 break 语句

6.switch 语句可以包含一个 default 分支,该分支一般是 switch 语句的最后一个分支,default 在没有 case 语句的值和变量值相等的时候执行default 分支不需要 break 语句

/* switch case 执行时,一定会先进行匹配,匹配成功返回当前 case 的值,再根据是否有 break,判断是否继续输出,或是跳出判断*/
public static void main(String args[]){
       //char grade = args[0].charAt(0);
       char grade = 'C';
switch(grade)
{
       case 'A' :
       System.out.println("优秀");
       break;
       case 'B' :
       case 'C' :
       System.out.println("良好");
       break;
       case 'D' :
       System.out.println("及格");
       break;
       case 'F' :
       System.out.println("你需要再努力努力");
       break;
default :
   System.out.println("未知等级");
}
   System.out.println("你的等级是 " + grade);
}
/*如果case 语句块中没有 break 语句时,匹配成功后,从当前 case 开始,后续所有case的值都会输出。如果后续的 case 语句块有 break 语句则会跳出判断,称为【case穿透】*/
public static void main(String args[]){
   int i = 1;
switch(i){
   case 0:
   System.out.println("0");
   case 1:
   System.out.println("1");
   case 2:
   System.out.println("2");
   case 3:
   System.out.println("3");
   break;
default:
   System.out.println("default");
 }//输出:1,2,3。
}   

JDK7增加了字符串表达式:

public static void main(String[] args) {
   String name = "小郭";
   switch (name) { 
  //JDK7的新特性,表达式结果可以是字符串!!!
   case "GuoJingPeng":
   System.out.println("GuoJingPeng");
   break;
   case "小郭":
   System.out.println("小郭");
   break;
default:
   System.out.println("终极输出");
break;
   }
}
3.4 循环结构
3.4.1 while 循环
while(布尔表达式) {
//循环内容
}
//计算1+2+3+…+100=?
public static void main(String[] args) {
   int i = 0;
   int sum = 0;
   while (i <= 100) {
     sum = sum+i;
     i++;
 }
   System.out.println("Sum= " + sum);
}
3.4.2 do…while 循环

一、对于 while 语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。

二、do…while 循环和 while 循环相似,不同的是,do…while 循环至少会执行一次。

do {
//代码语句
}while(布尔表达式);
计算1+2+3+…+100=?
public static void main(String[] args) {
   int i = 0;
   int sum = 0;
do {
   sum = sum+i;
   i++;
}while (i <= 100);
   System.out.println("Sum= " + sum);
}
3.4.3 while和do-while的区别:

1.while先判断后执行。dowhile是先执行后判断。

2.do…while总是保证循环体会被至少执行一次,这是他们的主要差别。

3.4.4 For循环

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

for(初始化; 布尔表达式; 更新) {
//代码语句
}
public static void main(String[] args) {
   int a = 1; //初始化
while(a<=100){ //条件判断
   System.out.println(a); //循环体
   a+=2; //迭代
}
   System.out.println("while循环结束!");
for(int i = 1;i<=100;i++){ //初始化//条件判断 //迭代
   System.out.println(i); //循环体
}
   System.out.println("while循环结束!");
}
3.4.5 增强for循环

Java5 引入了一种主要用于数组或集合的增强型 for 循环。

Java 增强 for 循环语法格式如下:

for(声明语句 : 表达式)
{
//代码句子
}
public static void main(String[] args) {
int [] numbers = {10, 20, 30, 40, 50};
  for(int x : numbers ){
  System.out.print( x );
  System.out.print(",");
 }
  System.out.print("\n");
  String [] names ={"James", "Larry", "Tom", "Lacy"};
for( String name : names ) {
  System.out.print( name );
  System.out.print(",");
  }
}
3.4.6 break 关键字

break 跳出最里层的循环,并且继续执行该循环下面的语句。

public static void main(String[] args) {
  int i=0;
while (i<100){
  i++;
  System.out.println(i);
if (i==30){
  break;
  }
 }
}
3.4.7 continue 关键字

continue 适用于任何循环控制结构中。作用是让程序立刻跳转到下一次循环的迭代。

public static void main(String[] args) {
   int i=0;
while (i<100){
   i++;
if (i%10==0){
   System.out.println();
   continue;
  }
   System.out.print(i);
 }
}
3.4.8 break与continue两者区别

1.break在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。(break语句也在switch语句中使用)

2.continue 语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行 下一次是否执行循环的判定。

4.JavaSE: 方法

4.1 方法的定义

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

修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
4.2 静态方法

1.使用static修饰符修饰的方法,就是静态方法。

2.调用这种方法的时候,可以使用对象调用,也可以使用类来调用,但是推荐使用类进行调用,因为静态方法是属于类的。

public class Student{
public static void say(){
}
	}
Student student = new Student;
student.say();//对象调用
Student.say();//类调用
4.3 非静态方法

1.没有使用static修饰符修饰的方法,就是非静态方法。

2.调用这种方法的时候,是一定要使用对象的,因为非静态方法是属于对象的。(非静态属性也是一样的)

public class Student{
public void say(){
}
	}
Student s = new Student();
s.say();//必须对象调用
4.4 方法的调用

1.假设同一个类中有俩个方法,a方法和b方法,a和b都是非静态方法,相互之间可以直接调用

public void a(){
b();//a调用b
}
public void b(){
a();//b调用a
}

2.a和b都是静态方法,相互之间可以直接调用

public static void a(){
	b();//a调用b
}
public static void b(){
	a();//b调用a
}

3.a静态方法,b是非静态方法, 静态方法不能调用非静态方法,而非静态方法可以调用静态方法

//并且在同一个类中,静态方法内不能直接访问到类中的非静态属性
public static void a(){
	b();//报错
}
public void b(){
	a();
}
4.5 形参与实参
public static void main(String[] args){
    int a = 1;
    t.test(x);//实参
}
public void test(int x)//形参
{
    /*....*/
}
4.6 值传递和引用传递

1.调用方法进行传参时,分为值传递引用传递两种。

2.值传递:参数的类型是基本数据类型

3.引用传递:参数的类型是引用数据类型

/*值传递*/
/*实参把自己变量本身存的简单数值赋值给形参*/
public class Test{
public static void changeNum(int a){
     a = 10;
     }
public static void main(String[] args){
     int a = 1;
     System.out.println(a); //1
   }
}     
/*引用传递*/
/*实参把自己变量本身存的对象内存地址值赋值给形参*/
public class Test{
public static void changeName(Student s){
       s.name = "tom";
        }
public static void main(String[] args){
       Student s = new Student();     
System.out.println(s.name); //tom
       }
   }
class Student{
String name;
}
4.7 this关键字

1.区别成员变量和局部变量

public class Student{
    private String name;
    public void setName(String name){
        //this.name表示类中的属性name
        this.name = name;
    }
}

2.调用类中的其他方法

public class Student{
    private String name;
    public void setName(String name){
        this.name = name;
    }
    public void print(){
	 //表示调用当前类中的setName方法
        this.setName("XiaoGuo");
    }
//默认情况下,setName()和this.setName()的效果是一样的
}

3.调用类中的其他构造器

public class Student{
    private String name;
    //调用一个参数的构造器,并且参数的类型是String
    public Student(String name){
        this.name = name;
    	}
    public Student(){
    	this.name("XiaoGuo")
	}
}
/*:this的这种用法,只能在构造器中使用,普通的方法是不能用的,并且调用语句必须在第一句*/
public class Student{
private String name;
public Student(){
		System.out.println("hello");
		this("tom");//编译报错
	   }
public Student(String name){
		this.name = name;
	}
}

4.表示类中创建的对象

public class Student{
private String name;
public Student(){
   System.out.println(this);//Student@606d8acf
     }
public static void main(String[] args){
	Student s = new Student();
	System.out.println(s);//Student@606d8acf
  }
}
/*这句话是要这么来描述的,s1对象中的this和s1相等,s2对象中的this和s2相等因为类是模板,模板中写的this并不是只有一个,每个对象中都有一个属于自己的this,就是每个对象中都一个属于自己的name属性一样*/
public class Student{
private String name;
public void test(){
       System.out.println(this);
      }
public static void main(String[] args) {
       Student s1 = new Student();
       Student s2 = new Student();
       s1.test();//Student@606d8acf
       s2.test();//Student@782830e
   }
}   
4.8 Super关键字

​ 一、子类继承父类之后,在子类中可以使用this来表示访问或调用子类中的属性或方法,而使用super就表示访问或调用父类中的属性和方法

//访问父类中的属性
public class Person{
protected String name = "xiaoguo";
		}
public class Student extends Person{
	private String name = "XiaoGuo";
  public void test(String name){
	System.out.println(name);
	System.out.println(this.name);
	System.out.println(super.name);
	}
}
//调用父类中的方法
public class Person{
public void print(){
      System.out.println("Person");
        }
      }
public class Student extends Person{
   public void print(){
      System.out.println("Student");
    }
public void test(){
      print();
      this.print();
      super.print();
  }
}      
//隐式调用父类的无参构造器
//父类存在无参构造
public class Person{
    public String name;
    }
public class Student extends Person{
		super();//编译通过
    public Student(String name){
   }
}
//显示调用父类的无参构造器
//父类没有无参构造
public class Person{
      protected String name;
    public Person(String name){
      this.name = name;
  	 }
	}
public class Student extends Person{
	super();//编译报错
	public Student(){
   }
}
//显式的调用父类的有参构造器
public class Person{
	protected String name;
  public Person(String name){
	this.name = name;
		}
     }
public class Student extends Person{
     public Student(){
     super("XiaoGuo");//编译通过
   }
}

​ 二、不管是显式还是隐式的父类的构造器,super语句一定要出现在子类构造器中第一行代码。所以this和super不可能同时使用它们调用构造器的功能,因为它们都要出现在第一行代码位置。

public class Person{
    protected String name;
public Person(String name){
    this.name = name;
    }
  }
public class Student extends Person{
public Student(){
     System.out.println("Student");
      super("XiaoGuo");//编译失败
 }
}
public class Person{
   protected String name;
 public Person(String name){
		this.name = name;
		}
      }

public class Student extends Person{
		private int age;
		public Student(){
		this(20);//编译通过
  }
public Student(int age){
		super("XiaoGuo");//编译通过
		this.age = age;
 }
}

三、super使用的注意的地方:

  1. 用super调用父类构造方法,必须是构造方法中的第一个语句

  2. super只能出现在子类的方法或者构造方法中

  3. super 和 this 不能够同时调用构造方法

4.9 this与Super的区别

一、代表的事物不一样

this:代表所属方法的调用者对象

super:代表父类对象的引用空间

二、使用前提不一致

this:在非继承的条件下也可以使用

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

三、调用构造方法不一致

this:调用本类的构造方法

super:调用父类的构造方法

4.10 方法的重载

创建另一个有相同名字但参数不同的方法

public static double max(double num1, double num2) {
if (num1 > num2)
      return num1;
else
      return num2;
}
public static int max(int num1, int num2) {
      int result;
if (num1 > num2)
      result = num1;
else
      result = num2;
      return result;
}
4.11 方法的重写

一、创建另一个有相同名字、相同参数、返回值类型相同的方法

/*
注意:
1.子类抛出的异常下不能超过父类相应方法抛出的异常
2.子类方法的访问级别不能低于父类相应方法的访问级别
3.静态方法不能重写
4.父类的静态方法不能被子类重写为非静态方法
5.父类的非静态方法不能被子类重写为静态方法
6.子类可以定义与父类的静态方法同名的静态方法(但是这个不是覆盖)
*/
//父类Animal
public class Animal {
    public String name; // 名字
    public int age; // 年龄
public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
public String getInfo() {
        return name + age ;
    }
}
//子类Cat
public class Cat extends Animal {
    private String hobby;
public Cat(String name, int age, String hobby) {
        super(name, age);
        this.hobby = hobby;
    }
public String getInfo() {
    return  this.name  + this.age+ hobby ;
    }

public static void main(String[] args) {
    Animal animal = new Cat("小郭", 18, "鱼");
    System.out.println(animal.getInfo());
    }
}

二、不能被重写的情况

  1. static方法,因为被static修饰的方法是属于类的,而不是属于实例的

  2. final方法,因为被final修饰的方法无法被子类重写

  3. private方法和protected方法,前者是因为被private修饰的方法对子类不可见,后者是因为尽管被protected修饰的方法可以被子类见到,也可以被子类重写,但是它是无法被外部所引用的

4.12 重写与重载区别

1.方法的重载是方法的参数个数或类型不同,方法名相同

2.方法重写是要注意权限的问题,子类中的权限不能小于父类的权限,当父类的权限为private时,子类无法继承。也就无法产生所谓的重写

3.修饰符高低:private < 默认修饰符 < public

4.13 可变参数

JDK 1.5 开始,Java支持传递同类型的可变参数给一个方法。

1.方法的可变参数的声明如下所示:

typeName... parameterName
 //在方法声明中,在指定参数类型后加一个省略号(...)

2.一个方法中只能指定一个可变参数,它必须是方法的最后一个参数,任何普通的参数必须在它之前声明。

public static void main(String args[]) {
      printMax(34, 3, 3, 2, 56.5);
      printMax(new double[]{1, 2, 3});
    }
public static void printMax( double... numbers)
{  // 调用可变参数的方法
  if (numbers.length == 0) {
      System.out.println("No argument passed");
      return;
   }
      double result = numbers[0];
//排序
for (int i = 1; i < numbers.length; i++){
  if (numbers[i] > result) {
      result = numbers[i];
  }
 }
      System.out.println("The max value is " + result);
}      
4.14 递归

一、 递归是一种常见的解决问题的方法,即把问题逐渐简单化。递归的基本思想就是“自己调用自己”,一个 使用递归技术的方法将会直接或者间接的调用自己。

二、递归结构包括两个部分:

  1. 递归头。解答:什么时候不调用自身方法,如果没有头,将陷入死循环。
  2. 递归体。解答:什么时候需要调用自身方法。
//利用代码计算5的乘阶!
public static void main(String[] args) {
   System.out.println(f(5));
}
   public static int f(int n) {
if (1 == n)
   return 1;
else
   return n*f(n-1);
}

5.JavaSE:数组

5.1 数组概述
5.1.1 数组的定义

1.数组是相同类型数据的有序集合.

2.数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。

3.其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们.

5.1.2 数组的特点
  1. 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。

  2. 其元素必须是相同类型,不允许出现混合类型。

  3. 数组中的元素可以是任何数据类型,包括基本类型和引用类型。

  4. 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的

5.2 声明数组
  1. 声明的时候并没有实例化任何对象,只有在实例化数组对象时,JVM才分配空间,这时才与长度有关。因此,声明数组时不能指定其长度,例如:int[5] a; //非法

  2. 声明一个数组的时候并没有数组被真正的创建。

double[] myList; // 首选的方法
double myList[]; // 效果相同,但不是首选方法
5.3 创建数组

1.Java语言使用new操作符来创建数组,语法如下:

arrayRefVar = new dataType[arraySize];

2.数组变量的声明,和创建数组可以用一条语句完成,如下所示:

dataType[] arrayRefVar = new dataType[arraySize];

3.演示创建一个数组,并赋值,进行访问:

public static void main(String[] args){
    //1.声明一个数组
    int[] myList = null;
    //2.创建一个数组
    myList = new int[10];// 构造一个数组,必须指定长度
    //3.向数组中存值
    myList[0] = 1;
    myList[1] = 2;
    myList[2] = 3;
    myList[3] = 4;
    //4.计算所有元素的总和
    double total = 0;
for (int i = 0; i < myList.length; i++)
{
    total += myList[i];
     }
    System.out.println("总和为: " + total);
}
5.4 三种初始化
5.4.1 静态初始化

除了用new关键字来产生数组以外,还可以直接在定义数组的同时就为数组元素分配空间并赋值。

int[] a ={1,2,3};
Man[] man = {new Man(1,2), new Man(3,4)}
5.4.2 动态初始化

数组定义、为数组元素分配空间、赋值的操作、分开进行。

int[] a = new int[2];//数组定义、分配空间
a[0] = 1;//赋值
a[1] = 2;
5.4.3 数组的默认初始化

数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

public static void main(String[] args){
    int[] a = new int[2];//初始化
    boolean b = new boolean[2];
    String c = new String[2];
    System.out.println(a[0]+":"+a[1]); //0,0
    System.out.println(b[0]+":"+b[1]); //false,false
    System.out.println(c[0]+":"+c[1]); //null, null
}
5.5 数组边界问题

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

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

数组的元素类型和数组的大小都是确定的,所以当处理数组元素时候,我们通常使用基本循环或者 ForEach 循环

public class TestArray{
    public staic void main(String[] args){
        //动态初始化
        double[] a = new double[10];
        a[1] = 1.1;
        a[2] = 2.2;
        a[3] = 3.3;
         // 打印所有数组元素
    for (int i = 0; i < myList.length; i++) {
       System.out.println(myList[i] + " ");
         }
         // 计算所有元素的总和
        double total = 0;
    for (int i = 0; i < myList.length; i++) {
         total += myList[i];
         }
        System.out.println("Total is " + total);
         // 查找最大元素
        double max = myList[0];
     for (int i = 1; i < myList.length; i++) {
       if (myList[i] > max) {
        max = myList[i];
      }
}
5.6.1数组作方法入参

数组可以作为参数传递给方法:

//一个打印int数组中元素的方法
public static void main(String[] args){
   public static printArray(int[] array){
       for(int i=0; i < array.length; i++){
        System.out.println(array[i]);   
       }
   }
}
5.6.2数组作为返回值
public	static int[] reverse(int[] list){
    int[] result = new int[list.length];
for (int i=0, j=result.length - 1;i <list.length;i++, j--) {
		result[j] = list[i];
	}
		return result;
}
5.7 多维数组

多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。

5.7.1 定义一个二维数组
int a[][] = new int[2][3];
//二维数组a可以看成一个两行三列的数组
5.7.2 获取数组长度
//a.length获取的二维数组第一维数组的长度,
//a[0].length才是获取第二维第一个数组长度。
5.8 Arrays类

一、数组的工具类java.util.Arrays;由于数组对象本身并没有什么方法可以供我们调用,但API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作

二、具有以下常用功能:

​ 1.给数组赋值:通过 fifill 方法。

​ 2.对数组排序:通过 sort 方法,按升序。

​ 3.比较数组:通过 equals 方法比较数组中元素值是否相等。

​ 4.查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。

5.8.1 打印数组
public static void main(String[] args){
    int[] a = {1,2};
    System.out.println(a);//@1b6d3586
    System.out.println(Arrays.toString(a));//[1, 2]
}
5.8.2 数组排序
//对指定的int型数组按数字升序进行排序
public static void main(String[] args) {
 int[] a = {1,2,323,23,543,12,59};
   System.out.println(Arrays.toString(a));
   Arrays.sort(a);//排序
   System.out.println(Arrays.toString(a));
}
5.8.3 二分法查找

1.必须在进行此调用之前对数组进行排序(通过sort方法等),如果没有对数组进行排序,则结果是不确定的。

2.如果数组包含多个带有指定值的元素,则无法保证找到的是哪一个

使用二分法查找,必须先对数组进行排序
public static void main(String[] args) {
   int[] a = {1,2,323,23,543,12,59};
   Arrays.sort(a);   System.out.println(Arrays.binarySearch(a,12));
}   
//元素填充
public static void main(String[] args) {
  int[] a = {1,2,323,23,543,12,59};
  Arrays.sort(a); //使用二分法查找,必须先对数组进行排序
  Arrays.fill(a, 2, 4, 100); //将2到4索引的元素替换为100
 System.out.println(Arrays.toString(a));
}
5.9 数组转为List集合

​ 通过Arrays.asList方法,该方法返回一个受指定数组支持的固定大小的列表。

    public static void main(String[] args) {
        int[] a = {3,5,1,9,7};
        List<int[]> list = Arrays.asList(a);
        for (int[] ab :list) {
            System.out.println(Arrays.toString(ab));
        }//[3, 5, 1, 9, 7]
    }
}

6.JavaSE: 面向对象

6.1 面向过程&面向对象

1.面向过程的思维模式

面向过程的思维模式是简单的线性思维,思考问题首先陷入第一步做什么、第二步做什么的细节中。这种思维模式适合处理简单的事情,比如:上厕所。无法面对复杂的事情,比如:如何造神舟十号

2.面向对象的思维模式

​ 面向对象的思维模式说白了就是分类思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。这样就可以形成很好的协作分工。

3.我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。

6.2 类与对象的关系

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

/*能够使用的是具体实例,而不是类,类只是给对象的创建提供了一个参考的模板而已*/
Student s = new Student(1L,"tom",20);
s.study();//对象s就是Student类的一个实例
Car c = new Car(1,"BWM",500000);
c.run();//对象c就是Car类的一个具体实例
6.3 对象和引用的关系

在程序中,创建出对象后,直接使用并不方便,所以一般会用一个引用类型的变量去接收这个对象,这个就是所说的引用指向对象。

Student student = new Student();
6.4 构造器

一、类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下俩个特点:

  1. 必须和类的名字相同

  2. 必须没有返回类型,也不能写void

二、构造器的作用

  1. 使用new创建对象的时候必须使用类的构造器

  2. 构造器中的代码执行后,可以给对象中的属性初始化赋值

public class Student{
    private String name;
    public Student(){ //无参构造
        name = "XiaoGuo";
    }
}
public class Student{
    private String name;
     public Student(){ //无参构造
        name = "XiaoGuo";
    }
    public Student(String name){ //有参构造(构造器重载)
        this.name = name;//在创建对象时候赋值
    }
}

三、默认构造器

​ 在java中,即使我们在编写类的时候没有写构造器,那么在编译之后也会自动的添加一个无参构造器,这个无参构造器也被称为默认的构造器。

public class Student{
    编译通过,因为默认存在无参构造器
    Student student = new Student();
}

​ 但是,如果我们手动的编写了一个构造器,那么编译后就不会添加任何构造器了

public class Student{
    public String name;
  public Student(String name){
    this.name = name;
  }
    Student student = new Student();
    //编译报错,因为编译时没有生成无参构造器
}
6.5 Java 三大特性
6.5.1 封装

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

二、封装的作用和意义:

​ 1.提高程序的安全性,保护数据

​ 2.隐藏代码的实现细节

​ 3.统一用户的调用接口

​ 4.提高系统的可维护性

​ 5.便于调用者调用。

三、封装的步骤

​ 1.使用private 修饰需要封装的成员变量

​ 2.提供一个公开的方法设置或者访问私有的属性

//set负责给属性赋值
//get负责返回属性的值
public class Student{
private String name;
public void setName(String name){
	this.name = name;
		 }
public String getName(){
	return this.name;
 	  }
  }
public class Test{
public static void main(String[] args){
	Student s = new Student();
	s.setName("XiaoGuo");
	System.out.println(s.getName());
}
6.5.2 继承

​ 1. 继承是类和类之间的一种关系,除此之外,类和类之间的关系还有依赖、组合、聚合等

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

  2. Java中类与类之间为单继承:一个子类只能"直接"继承一个父类,就像是一个人只能有一个亲生父亲。但是一个父类可以被多子类继承,就像一个父亲可以有多个孩子

  3. Java中接口和接口之间,可以继承,并且是多继承

  4. 父类中的属性和方法使用public修饰,在子类中继承后"可以直接"使用

  5. 父类中的属性和方法使用private修饰,在子类中继承后"不可以直接"使用

  6. 父类中的构造器是不能被子类继承的,但是子类的构造器中,会隐式的调用父类中的无参构造器(默认使用super关键字)

    public class Father{
        //.....
    }
    public class Son extend Father{
        //.....
    }
    
6.5.3 多态

一、多态可以让我们不用关心某个对象到底是什么具体类型,就可以使用该对象的某些方法,从而实现更加灵活的编程,提高系统的可扩展性。

二、允许不同类的对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式。

三、相同类域的不同对象,调用相同的方法,执行结果是不同的

//Student继承了Person类
//Person和Object都是Student的父类型
Student s1 = new Student();
Person s2 = new Student();
Object s3 = new Student();
public class Person{
    person.test;//编译报错,编译器检查变量类型是Person,但是在Person类中并没有发现test方法
public void run(){
		}
	  }
public class Student extends Person{
  Person person = new Student();
    person.run;//通过
	public void test(){
	}
}
6.5.3.1多态的注意事项
  1. 多态是方法的多态,属性没有多态性。

  2. 编写程序时,如果想调用运行时类型的方法,只能进行类型转换。不然通不过编译器的检查。但是如果两个没有关联的类进行强制转换,会报:ClassCastException。 比如:本来是狗,我把它转成猫。就会报这个异常。

  3. 多态的存在要有3个必要条件:要有继承,要有方法重写,父类引用指向子类对象

6.5.3.2 多态存在的条件
  1. 继承关系

  2. 子类重写父类方法

  3. 父类引用指向子类对象

6.5.3.3 instanceof和类型转换

一、instanceof

​ 1.能否编译通过,主要是看是否存在子父类的关系

​ 2.输出结果是true还是false,主要是看是左边是不是右边的子类型

public class Person{
    Person o1 = new Student();
public void run(){}
		}
public class Student extends Person{
    Object o2 = new Student();
    Student o3 = new Student();
	}
public class Teacher extends Person{
    Teacher o4 = new Teacher();
}
main:
System.out.println(o1 instanceof Teacher);//false
System.out.println(o2 instanceof Student);//true
System.out.println(o3 instanceof Object);//true
System.out.println(o4 instanceof Person);//false

二、类型转换

public class Person{
	public void run(){}
	}
public class Student extends Person{
	public void go(){}
	}
public class Teacher extends Person{
}
main:
	//编译报错,因为p声明的类型Person中没有go方法
	Person p = new Student();
	p.go();
	//需要把变量p的类型进行转换
	Person p = new Student();
	Student s = (Student)p;
	s.go();
	//注意这种写法前面必须要俩个小括号
	((Student)p).go();
	//编译通过,运行报错
	Object o = new Student();
	Student s = (Student)o;
	//X x = (X)o;
//运行是否报错,主要是变量o所指向的对象实现类型,是不是X类型的子类型,如果不是则运行就会报错

三、总结

​ 1.父类引用可以指向子类对象,子类引用不能指向父类对象

​ 2.子类对象直接赋给父类引用叫向上转型,向上转型不用强制转型,如:Father father = new Son();

​ 3.把指向子类对象的父类引用赋给子类引用叫向下转型,要强制转型。如father就是一个指向子类对象的父类引用,把father赋给子类引用son 即Son son = (Son)father;其中father前面的(Son)必须添加,进行强制转换

​ 4.向上转型会丢失子类特有的方法,但是子类重写父类的方法,仍然可用

​ 5.向上转型的作用,减少重复代码,父类为参数,调有时用子类作为参数,就是利用了向上转型,这样使代码变得简洁,体现了Java抽象编程思想

6.6 修饰符
6.6.1 static修饰符
6.6.1.1 static常量

1.由static修饰的常量称为静态常量,否之为非静态常量

2.静态常量属于类,通过类进行访问

3.非静态变量是属于对象的,"必须"使用对象来访问

//在加载类的过程中为静态变量分配内存,实例变量在创建对象时分配内存,所以静态变量可以使用类名来直接访问,而不需要使用对象来访问
public class Student{
	private static int age;
	private double score;
public static void main(String[] args) {
	Student s = new Student();
	//推荐使用类名访问静态成员
	System.out.println(Student.age);
	System.out.println(s.age);
	System.out.println(s.score);
	}
}
6.6.1.2 static方法

1.使用static修饰的成员方法,就是静态方法,反之为非静态方法

2.静态方法"不可以"直接访问类中的非静态变量非静态方法,但是"可以"直接访问类中的静态变量和静态方法

3.this和super在类中属于非静态的变量

4.静态方法和非静态方法不能直接相互访问—> 加载顺序的问题

public class Student{
	private static int count;
	private int num;
	public void run(){}
	public static void go(){}
	public static void test(){
	System.out.println(count);//编译通过
	go();//编译通过
	System.out.println(num);//编译报错
	run();//编译报错
}
//父类的静态方法可以被子类继承,但是不能被子类重写
public class Person {
public static void method() {}
	}
public class Student extends Person {
public void method(){}//编译报错
}
//父类的非静态方法不能被子类重写为静态方法
public class Person {
public void method() {}
	}
public class Student extends Person {
public static void method(){}//编译报错
}
6.6.1.3 代码块和静态代码块

一、匿名代码块和静态代码块的执行

1.因为没有名字,在程序并不能主动调用这些代码块

2.匿名代码块是在创建对象的时候自动执行的,并且在构造器执行之前,同时匿名代码块在每次创建对象的时候都会自动执行

3.静态代码块是在类加载完成之后就自动执行,并且只执行一次

4.每个类在第一次被使用的时候就会被加载,并且一般只会加载一次

二、匿名代码块和静态代码块的作用

1.匿名代码块的作用是给对象的成员变量初始化赋值,但是因为构造器也能完成这项工作,所以匿名代码块使用的并不多

2.静态代码块的作用是给类中的静态成员变量初始化赋值

public class Person {
{
//代码块(匿名代码块)
}
static{
//静态代码块
}
public Person(){
System.out.println("构造器");
	}
}

三、创建和初始化对象的过程

​ 1. 类加载,同时初始化类中静态的属性

​ 2. 执行静态代码块

​ 3. 分配内存空间,同时初始化非静态的属性(赋默认值,0/false/null)

​ 4. 调用Student的父类构造器

​ 5. 对Student中的属性进行显示赋值(如果有的话)

​ 6. 执行匿名代码块

​ 7. 执行构造器

​ 8.返回内存地址

Student student = new Student();
6.6.1.4 静态导入

1.静态导包就是java包的静态导入,用import static代替import静态导入包是JDK1.5中的新特性,意思是导入这个类里的静态方法。

2.好处:这种方法的好处就是可以简化一些操作,例如打印操作System.out.println(…);就可以将其写入一个静态方法print(…),在使用时直接print(…)就可以了。但是这种方法建议在有很多重复调用的时候使用,如果仅有一到两次调用,不如直接写来的方便。

import static java.lang.Math.random;
import static java.lang.Math.PI;
  public class Test {
  public static void main(String[] args) {
   //之前是需要Math.random()调用的
	System.out.println(random());
	System.out.println(PI);
	}
6.6.2 final修饰符
6.6.2.1 修饰类

1.用final修饰的类不能被继承,没有子类

2.无法写一个类去继承String类,然后对String类型扩展的,因为API中已经被String类定义为final

public final class Action{
}
public class Go extends Action{
    //编译报错
}
6.6.2.2 修饰方法

1.使用final修饰的方法可以被继承,但是不能被子类的重写

2.每个类都是Object类的子类,继承了Object中的众多方法,在子类中可以重写toString方法、equals方法等,但是不能重写getClass方法、 wait方法等,因为这些方法都是使用fifianl修饰的

public class Person{
public final void print(){}
		}

public class Student extends Person{
public void print(){//编译报错
	}
}

6.6.2.3 修饰变量

1.用final修饰的变量表示常量,只能被赋值一次

2.经过final修饰后的变量值不可再改变,也就成为常量了

//修饰局部变量
public class Person{
public void print(final int a){
	//编译报错,不能再次赋值,传参的时候已经赋过了
		a = 1;
   	   }
	 }
public class Person{
public void print(){
		final int a;
		a = 1;
		//编译报错,不能再次赋值
		a = 2;
	}
}
//修饰成员变量或非静态成员变量
public class Person{
	private final int a;
}
//修饰成员变量或静态成员变量
public class Person{
	private static final int a;
}
//修饰引用变量
main:
    final Student s = new Student();
//编译通过
	s.setName("XiaoGuo");
//编译报错,不能修改引用s指向的内存地址
	s = new Student();
6.6.3 abstract修饰符

​ abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类

一、抽象类和抽象方法的关系

​ 1.抽象类中可以没有抽象方法

​ 2.有抽象方法的类一定要声明为抽象类

二、语法

​ 声明方法的时候,加上abstract修饰符,并且去掉方法的大口号,同时结尾加上分号,该方法就是抽象方法

public abstract class Action{
public abstract void doSomething();
}

三、特点及作用

​ 1.抽象方法只有方法的声明,没有方法的实现,需要子类继承后实现

​ 2.抽象类不能new对象,它是让子类继承的

​ 3.子类继承抽象类后,需要实现抽象类的方法,否则这个子类也要声明为抽象类

public abstract class Action{
public abstract void doSomething();
}
main:
	//编译报错,抽象类不能new对象
	Action a = new Action();
	//子类继承抽象类
 public class Eat extends Action{
	//实现父类中没有实现的抽象方法
 public void doSomething(){
	//....
	}
}
main:
Action a = new Eat();
a.doSomething();

四、思考

1.抽象类不能new对象,那么抽象类中有没有构造器?

​ 抽象类是不能被实例化,抽象类的目的就是为实现多态中的共同点,抽象类的构造器会在子类实例化时调用,因此它也是用来实现多态中的共同点构造,不建议这样使用!

2.抽象类和抽象方法意义?

​ 打个比方,要做一个游戏,如果要创建一个角色,如果反复创建类和方法会很繁琐和麻烦。建一个抽象类后。若要创建角色可直接继承抽象类中的字段和方法,而抽象类中又有抽象方法。如果一个角色有很多种职业,每个职业又有很多技能,要是依次实例这些技能方法会显得想当笨拙。定义抽象方法,在需要时继承后重写调用,可以省去很多代码

​ 总之抽象类和抽象方法起到一个框架作用,很方便后期的调用和重写

​ 抽象方法是为了程序的可扩展性,重写抽象方法时即可实现同名方法但又非同目的的要求

6.7 接口

一、接口的本质探讨

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

​ 2.接口的本质是契约,就像我们人间的法律一样,制定好后大家都遵守

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

二、普通类、抽象类、接口的区别

​ 1.普通类:只有具体实现

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

​ 3.接口:只有规范

三、接口中的方法都是抽象方法

​ 接口中可以不写任何方法,但是写方法就必须是抽象方法

public interface Action{
  //默认就是public abstract修饰的
  void toAction();
}

四、接口中的变量都是静态常量(public static final修饰)

​ 1.接口中可以不写任何属性,如果写必须使用public static final修饰

​ 2.声明的时候就必须赋值,因为接口中不能写静态代码块

​ 3.可以直接使用接口名访问其属性。因为是public static修饰

public interface Action{
public static final String NAME = "tom";
	//默认就是public static final修饰的
	int AGE = 20;
  }
main:
	System.out.println(Action.NAME);

五、一个类可以实现多个接口

public interface A{}
public interface B{void testAction();}
public class Action implements A,B{
    //Student需要实现接口A和B中所有的抽象方法
   //否则Student类就要声明为抽象类,因为有抽象方法没实现
     public void testAction(){
        System.out.println("XiaoGuo")
    }
        A s1 = new Student();
		  s1.test();
	    B s2 = new Student();
	      s2.run();
}

六、一个接口可以继承多个父接口

public interface A{}
public interface B{void test();}
public interface Action extends A,B{
	 public void testAction(){
      //Student需要实现接口A和B中所有的抽象方法
        System.out.println("XiaoGuo")
    }
}

七、接口的作用

​ 接口的最主要的作用是达到统一访问,就是在创建对象的时候用接口创建,这样你像用哪个类的对象就可以new哪个对象了,不需要改原来的代码。这个就叫统一访问,因为你实现这个接口的类的方法名相同,但是实现内容不同

//[接口名] [对象名] = new [实现接口的类]
public class Son implements Father {
    Father father = new Son();
    public Son()  {
        System.out.println(father.getClass());
    }
}
public interface Father {
}

八、总结

​ 1.接口中没有构造方法,不能被实例化

​ 2.一个接口不能实现(implements)另一个接口,但它可以继承多个其它的接口

​ 3.Java接口必须通过类来实现它的抽象方法

​ 4.一个类只能继承一个直接的父类,但可以实现多个接口,间接的实现了多继承

​ 5.Java接口中的成员变量默认都是public,static,final类型的(都可省略),必须被初始化

​ 6.Java接口中的方法默认都是public,abstract类型的(都可省略),没有方法体,不能被实例化

​ 7.Java接口中只能包含public,static,final类型的成员变量和public,abstract类型的成员方法

​ 8.当类实现了某个Java接口时,它必须实现接口中的所有抽象方法,否则这个类必须声明为抽象类

​ 9.不允许创建接口的实例(实例化),但允许定义接口类型的引用变量,该引用变量引用实现了这个接口的类的实例

6.8内部类

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

6.8.1成员内部类

​ 1.成员内部类中不能写静态属性和方法

​ 2.成员内部类可以访问外部类的所有属性(包括私有的成员变量和方法)

​ 3.如果内部类中的变量名和外部类的成员变量名一样,要通过创建外部类对象 "."属性来访问外部类 属性,通过this.属性访问内部类成员属性

//定义一个内部类
public class Outer {
private int id;
public void out(){
	System.out.println("这是外部类方法");
		}
	class Inner{
	public void in(){
	System.out.println("这是内部类方法");
	}
  }
}
//实例化内部类
public class Test{
public static void main(String[] args) {
	//实例化成员内部类分两步
	//1、实例化外部类
	Outer outObject = new Outer();
	//2、通过外部类调用内部类
	Outer.Inner inObject = outObject.new Inner();
	//测试,调用内部类中的方法
    inObject.in();//打印:这是内部类方法
	}
}
//内部类访问外部类私有的成员变量
public void useId(){
		System.out.println(id+3);}
//内部类访问外部类的方法
public void useOut(){
		out();
}

//一般都是隐式调用
//当内部类中有属性或者方法名和外部类中的属性或方法名相同的时候,显示调用Outher.this
public class Outer {
		private int id;//默认初始化0
   public void out(){
    	System.out.println("这是外部类方法");
		}
class Inner{
		private int id=8; //这个id跟外部类的属性id名称一样。
	public void in(){
		System.out.println("这是内部类方法");
	}
    public void test(){
		System.out.println(id);//8
	System.out.println(Outer.this.id);//输出外部类的属性id=0
	}
 }
}
6.8.2静态内部类

​ 1.static修饰成员变量:整个类的实例共享静态变量

​ 2.static修饰方法:静态方法,只能够访问用static修饰的属性或方法,而非静态方法可以访问static修饰的方法或属性

​ 3.被static修饰了的成员变量和方法能直接被类名调用

​ 4.static不能修饰局部变量,切记,不要搞混淆了,static平常就用来修饰成员变量和方法

​ 5.静态内部类中可以声明静态方法和静态变量,但是非静态内部类中就不可以声明静态方法和静态变量

​ 6.静态内部类能够直接被外部类给实例化,不需要使用外部类对象

    Outer.Inner inner = new Outer.Inner();
6.8.3局部内部类

​ 1.局部内部类是在一个方法内部声明的一个类

​ 2.局部内部类中可以访问外部类的成员变量及方法

​ 3.局部内部类中如果要访问该内部类所在方法中的局部变量,那么这个局部变量就必须是final修饰的

​ 4.final修饰变量:变为常量,会在常量池中放着,逆向思维想这个问题,如果不实用final修饰,当局部内部类被实例化后,方法弹栈,局部变量随着跟着消失,这个时候局部内部类对象在想去调用该局部变量,就会报错,因为该局部变量已经没了,当局部变量用final修饰后,就会将其加入常量池中,即使方法弹栈了,该局部变量还在常量池中呆着,局部内部类也就是够调用。所以局部内部类想要调用局部变量时,需要使用final修饰,不使用,编译度通不过

public class Outer {
private int id;
//在method01方法中有一个Inner内部类,这个内部类就称为局部内部类
public void method01(){
    局部内部类要定义在方法中
	class Inner{
	public void in(){
        final String myname="";//必须使用final
        //private static int age;不能定义静态属性
		System.out.println("这是局部内部类");
				}
			}
//局部内部类不能通过外部类对象直接实例化,而是在方法中实例化出自己来
//通过内部类对象调用自己类中的方法
	Inner In = new Inner();
//局部内部类只能在自己的方法中用,因为局部内部类相当于一个局部变量,除了方法就找不到了
	In.in();
		}
	}
}
6.8.4匿名内部类
6.8.4.1匿名对象

​ 如果一个对象只要使用一次,那么我们就是需要new Object().method(), 就可以了,而不需要给这个实例保存到该类型变量中去,这就是匿名对象。

public class Test {
public static void main(String[] args) {
//将new出来的Student实例赋给student变量保存起来,但是我们只需要用一次,就可以这样写
	  Student student = new Student();
	  Student.eat();
	  //这种就叫做匿名对象的使用,不把实例保存到变量中。
	  new Student().eat();
			}
		}
class Apple{
	public void eat(){
     System.out.println("XiaoGuo");
	}
}
6.8.4.2匿名内部类

​ 一、匿名内部类跟匿名对象是一个道理,我也只需要用一次,那我就不需要在类中先定义一个内部类,而是等待需要用的时候,我 就在临时实现这个内部类,因为用次数少,可能就这一次,那么这样写内部类,更方便。不然先写出一 个内部类的全部实现来,然后就调用它一次,岂不是用完之后就一直将其放在那,那就没必要那样。

​ 二、 匿名内部类需要依托于其他或者接口来创建

​ 1.如果依托的是类,那么创建出来的匿名内部类就默认是这个类的子类

​ 2.如果依托的是接口,那么创建出来的匿名内部类就默认是这个接口的实现类

​ 三、 匿名内部类的声明必须是在使用new关键字的时候,匿名内部类的声明及创建对象必须一气呵成,并且之后能反复使用,因为没有名字

public class Test {
public static void main(String[] args) {
//如果我们需要使用接口中的方法,我们只需要走一步,就是使用匿名内部类,直接将其类的对象创建出来。
		new Test1(){//匿名内部类
 public void method(){
	System.out.println("实现了Test接口的方法");	}
			}.method();
		}
}
interface Test1{
	public void method();
}
//其实只要明白一点,new Test1(){实现接口中方法的代码}; Test1(){...}这个的作用就是将接口给实现了,只不过这里实现该接口的是一个匿名类,也就是说这个类没名字
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

养匹小马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值