您的位置:首页 > 编程语言 > Java开发

Java基础复习(一)

2017-03-23 23:39 246 查看
该复习笔记是基于传智播客的Java基础视频-深入简出精华版,链接: https://pan.baidu.com/s/1bp7NuOJ,建议刚刚入门的小白不要看,因为涉及太多的细节了,看多了反而让你容易放弃Java之路,刚刚入门的小白推荐下面这一套视频-链接:https://pan.baidu.com/s/1pLuAj5x

博主声明一下:我不是传智播客的什么托,只是一个菜鸟,现在在补着Java基础,搞了一套传智播客的Java视频以及Android视频,所以笔记可能会常出现这些字眼,请言语讽刺我是托的麻烦你闭嘴哈

建议

一个牛人给Java初学者的建议 - 云+社区 - 腾讯云

注意:学习编程就要耐得住寂寞,很多人不是学不了编程,而是看到编程需要掌握的知识太多或者遇到一点小毛病就放弃,这样的人其实学习哪一门知识都是不给力的,只因为他没有一颗耐得住寂寞的心

常见的DOS下的命令



Java基础

JAVA之旅(一)——基本常识,JAVA概念,开发工具,关键字/标识符,变量/常量,进制/进制转换,运算符,三元运算-博客-云栖社区-阿里云

标识符中常见的命名规则(了解)

见名知意

A:包

最好是域名倒过来,要求所有的字母小写

B:类或者接口

如果是一个单词首字母大写

如果是多个单词每个单词首字母大写(驼峰标识)

C:方法或者变量

如果是一个单词全部小写

如果是多个单词,从第二个单词首字母大写

D:常量

如果是一个单词,所有字母大写

如果是多个单词,所有的单词大写,用下划线区分每个单词

字面值常量

其中较为特殊的是:

字符常量 用单引号括起来的内容,里面只能放单个数字,单个字母或单个符号

空常量 null(数组部分讲解)

自定义常量(面向对象部分讲)

不同进制数据的表现形式(掌握)

A:二进制的数据表现形式

由0,1组成。以0b(b可以大写也可以小写)开头(JDK1.7版本可以表示二进制了)

B:八进制的数据表现形式

由0,1,…7组成。以0开头

C:十进制的数据表现形式

由0,1,…9组成。整数默认是十进制的

D:十六进制的数据表现形式

由0,1,…9,a,b,c,d,e,f(大小写均可)。以0x开头

E:案例演示

输出不同进制表现100的数据。

0b100 输出4(使用二进制)

0100 输出64(使用八进制)

100 输出100(使用十进制)

0x100 输出256(使用十六进制)

其他进制转十进制



十进制转其他进制



快速的进制转换



原码反码补码(了解)

A:为什么要学习原码反码补码?

原码, 反码, 补码 详解

B:有符号数据表示法的几种方式

原码

就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。

通过一个字节,也就是8个二进制位表示+7和-7

0(符号位) 0000111

1(符号位) 0000111

反码

正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。

补码

正数的补码与其原码相同;负数的补码是在其反码的末位加1。



「C基础」位运算 - Liquor - 博客园

基本数据类型分类(4类8种)

整数型

byte 占一个字节 -128到127

short 占两个字 -2^15~2^15-1

int 占四个字节 -2^31~2^31-1

long 占八个字节 -2^63~2^63-1

浮点型

float 占四个字节 -3.403E38~3.403E38 单精度

double 占八个字节-1.798E308~1.798E308 双精度

字符型

char 占两个字节 0~65535

但一个char只能放一个字母或者一个符号或者一个数字(放一个中文字是没有问题的)

布尔型

boolean

boolean理论上是占八分之一个字节,因为一个开关就可以决定是true和false了,但是java中boolean类型没有明确指定他的大小

面试题之变量相加和常量相加的区别(掌握)

A:案例演示

面试题:看下面的程序是否有问题,如果有问题,请指出并说明理由。

byte b1 = 3;

byte b2 = 4;

byte b3 = b1 + b2;

从两方面去回答这个题

b1和b2是两个变量,变量里面存储的值都是变化的,所以在程序运行中JVM是无法判断里面具体的值

byte类型的变量在进行运算的时候,会自动类型提升为int类型

byte b4 = 3 + 4;

3和4都是常量,java有常量优化机制,就是在编译的的时候直接把3和4的结果赋值给b4了

参考技术好文章:Java基础案列斥候7300新浪博客

注意事项:

进行混合运算的时候,byte,short,char不会相互转换,都会自动类型提升为int类型,其他类型进行混合运算的是小的数据类型提升为大的

byte,short,char – int – long – float – double

任何数据类型用+与字符串相连接都会产生新的字符串

System.out.println(“hello”+’a’+1); //运算结果:helloa1

System.out.println(‘a’+1+”hello”); //运算结果:98hello

Java语言中的字符char可以存储一个中文汉字吗?为什么呢?

可以。因为Java语言采用的是Unicode编码。Unicode编码中的每个字符占用两个字节。中文也是占的两个字节

所以,Java中的字符可以存储一个中文汉字

算术运算符的基本用法(掌握)

A:什么是运算符

就是对常量和变量进行操作的符号。

B:运算符的分类

算术运算符,赋值运算符,比较(关系或条件)运算符,逻辑运算符,位运算符,三目(元)运算符

C:算数运算符有哪些

+,-,*,/,%,++,–

D:注意事项:

a:+号在java中有三种作用,代表正号,做加法运算,字符串的连接符

b:整数相除只能得到整数。如果想得到小数,必须把数据变化为浮点数类型

c:/获取的是除法操作的商,%获取的是除法操作的余数

%运算符

当左边的绝对值小于右边绝对值时,结果是左边

当左边的绝对值等于右边或是右边的倍数时,结果是0

当左边的绝对值大于右边绝对值时,结果是余数

%运算符结果的符号只和左边有关系,与右边无关

任何一个正整数%2结果不是0就是1可以用来当作切换条件

逻辑运算符的基本用法(掌握)

&逻辑与:有false则false。

|逻辑或:有true则true。

^逻辑异或:相同为false,不同为true。

!逻辑非:非false则true,非true则false。

特点:偶数个不改变本身。

逻辑运算符&&和&的区别

A:案例演示

&&和&的区别?

a:最终结果一样。

b:&&具有短路效果。左边是false,右边不执行。

&是无论左边是false还是true,右边都会执行

||跟|区别和上面的一样的意思,虽然最终结果是一样的,但||左边是true,右边就不执行了

位异或运算符的特点及面试题(掌握)

Java的位运算符详解实例——与(&)、非(~)、或(|)、异或(^) - 坦GA的博客 - CSDN博客

位运算符^的特点:一个数据对另一个数据位异或两次,该数本身不变。

B:面试题:

请自己实现两个整数变量的交换

/*
* 位异或运算符的特点

* ^的特点:一个数据对另一个数据位异或两次,该数本身不变。
*/

//System.out.println(5 ^ 10 ^ 10);    //结果是5
//System.out.println(5 ^ 10 ^ 5);     //结果是

/*
* 请自己实现两个整数变量的交换(不需要定义第三方变量)
* 注意:以后讲课的过程中,我没有明确指定数据的类型,默认int类型。
*/

int x = 10;
int y = 5;

//需要第三方变量,开发推荐用这种
/*int temp;
temp = x;
x = y;
y = temp;*/

//不需要定义第三方变量,有弊端,有可能会超出int的取值范围
/*x = x + y;                //10 + 5 = 15
y = x - y;              //15 - 5 = 10
x = x - y;              //15 - 10 = 5*/

//不需要第三方变量,通过^来做
x = x ^ y;              // 10 ^ 5
y = x ^ y;              // 10 ^ 5 ^ 5   y = 10
x = x ^ y;              // 10 ^ 5 ^ 10  x = 5


位运算符的基本用法2及面试题(了解)

A:案例演示 >>,>>>,<<的用法:

<<:左移 左边最高位丢弃,右边补齐0

左移,向左移动几位就是乘以2的几次幂

>>:右移 最高位是0,左边补齐0;最高为是1,左边补齐1

右移,向右移动几位就是除以2的几次幂

>>>:无符号右移 无论最高位是0还是1,左边补齐0

键盘录入的基本格式讲解(掌握)

如何实现键盘录入呢?

先照格式来。

a:导包

格式:

import java.util.Scanner;

位置:

在class上面。

b:创建键盘录入对象

格式:

Scanner sc = new Scanner(System.in);

c:通过对象获取数据

格式:

int x = sc.nextInt();

选择结构switch语句的练习(掌握)

基本数据类型可以接收byte,short,char,int

引用数据类型可以接收枚举(JDK1.5),String字符串(JDK1.7)

a:case后面只能是常量,不能是变量,而且,多个case后面的值不能出现相同的

b:default可以省略吗?

可以省略,但是不建议,因为它的作用是对不正确的情况给出提示。

d:default一定要在最后吗?

不是,可以在任意位置。但是建议在最后。不是放在最后的时候,因为switch语句按照顺序执行,它没有break的话,会穿透

e:switch语句的结束条件

a:遇到break就结束了

b:执行到switch的右大括号就结束了

数组

整数类型:byte,short,int,long默认初始化值都是0

浮点类型:float,double默认初始化值都是0.0

布尔类型:boolean默认初始化值false

字符类型:char默认初始化值’\u0000’

char在内存中占的两个字节,是16个二进制位

\u0000,每一个0其实代表的是16进制的0,那么四个0就是代表16个二进制位

[I@19bb25a

[代表是数组,几个就代表几维

I代表是int类型

@是固定的

19bb25a代表的是数组的地址值

Java中的内存分配以及栈和堆的区别

A:栈(掌握)

存储局部变量

B:堆(掌握)

存储new出来的数组或对象

C:方法区

面向对象部分讲解

D:本地方法区

和系统相关

E:寄存器

给CPU使用

Java中的参数传递问题

基本数据类型的值传递,不改变原值,因为调用后就会弹栈,局部变量随之消失

引用数据类型的值传递,改变原值,因为即使方法弹栈,但是堆内存数组对象还在,可以通过地址继续访问

Java中到底是传值还是传址?

1,既是传值,也是传地址,基本数据类型传递的值,引用数据类型传递的地址

2,java中只有传值,因为地址值也是值(出去面试都说这种,支持者是高司令(java之父))

成员变量和局部变量的区别(掌握)

A:在类中的位置不同

成员变量:在类中方法外

局部变量:在方法定义中或者方法声明上

B:在内存中的位置不同

成员变量:在堆内存(成员变量属于对象,对象进堆内存)

局部变量:在栈内存(局部变量属于方法,方法进栈内存)

C:生命周期不同

成员变量:随着对象的创建而存在,随着对象的消失而消失

局部变量:随着方法的调用而存在,随着方法的调用完毕而消失

D:初始化值不同

成员变量:有默认初始化值

局部变量:没有默认初始化值,必须定义,赋值,然后才能使用。

注意事项:

局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。

基本数据类型变量包括哪些:byte,short,int,long,float,double,boolean,char

引用数据类型变量包括哪些:数组,类,接口,枚举

面向对象

Java面向对象思想和三大特性:java面向对象思想和三大特性 - 黑马飞的博客 - 博客频道 - CSDN.NET

静态变量和成员变量的区别(掌握)

静态变量也叫类变量 成员变量也叫对象变量

A:所属不同

静态变量属于类,所以也称为为类变量

成员变量属于对象,所以也称为实例变量(对象变量)

B:内存中位置不同

静态变量存储于方法区的静态区

成员变量存储于堆内存

C:内存出现时间不同

静态变量随着类的加载而加载,随着类的消失而消失

成员变量随着对象的创建而存在,随着对象的消失而消失

D:调用不同

静态变量可以通过类名调用,也可以通过对象调用

成员变量只能通过对象名调用

static的注意事项(掌握)

A:static的注意事项

a:在静态方法中是没有this关键字的

如何理解呢?

静态是随着类的加载而加载,this是随着对象的创建而存在。

静态比对象先存在。

b:静态方法只能访问静态的成员变量和静态的成员方法

静态方法:

成员变量:只能访问静态变量

成员方法:只能访问静态成员方法

非静态方法:

成员变量:可以是静态的,也可以是非静态的

成员方法:可是是静态的成员方法,也可以是非静态的成员方法。

简单记:

静态只能访问静态。

代码块(了解)

A:代码块概述

在Java中,使用{}括起来的代码被称为代码块。

B:代码块分类

根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)。

C:常见代码块的应用

a:局部代码块

在方法中出现;限定变量生命周期,及早释放,提高内存利用率

b:构造代码块 (初始化块)

在类中方法外出现;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行

c:静态代码块

在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次。

一般用于加载驱动

继承

A:继承的注意事项

a:子类只能继承父类所有非私有的成员(成员方法和成员变量)

b:子类不能继承父类的构造方法,但是可以通过super(马上讲)关键字去访问父类构造方法。

c:不要为了部分功能而去继承

this和super的区别和应用(掌握)

A:this和super都代表什么

this:代表当前对象的引用,谁来调用我,我就代表谁

super:代表当前对象父类的引用

B:this和super的使用区别

a:调用成员变量

this.成员变量 调用本类的成员变量,也可以调用父类的成员变量

super.成员变量 调用父类的成员变量

b:调用构造方法

this(…) 调用本类的构造方法

super(…) 调用父类的构造方法

c:调用成员方法

this.成员方法 调用本类的成员方法,也可以调用父类的方法

super.成员方法 调用父类的成员方法

继承中构造方法的关系(掌握)

A:案例演示

子类中所有的构造方法默认都会访问父类中空参数的构造方法

B:为什么呢?

因为子类会继承父类中的数据,可能还会使用父类的数据。

所以,子类初始化之前,一定要先完成父类数据的初始化。

其实:

每一个构造方法的第一条语句默认都是:super() Object类最顶层的父类。

方法重写的注意事项(掌握)

A:方法重写注意事项

a:父类中私有方法不能被重写

因为父类私有方法子类根本就无法继承

b:子类重写父类方法时,访问权限不能更低

最好就一致

c:父类静态方法,子类也必须通过静态方法进行重写

其实这个算不上方法重写,但是现象确实如此,至于为什么算不上方法重写,多态中我会讲解(静态只能覆盖静态)

子类重写父类方法的时候,最好声明一模一样。

方法重写的面试题(掌握)

A:方法重写的面试题

Override(重写)和Overload(重载)的区别?Overload能改变返回值类型吗?

overload可以改变返回值类型,只看参数列表

方法重写:子类中出现了和父类中方法声明一模一样的方法。与返回值类型有关,返回值是一致(或者是子父类)的

方法重载:本类中出现的方法名一样,参数列表不同的方法。与返回值类型无关。

子类对象调用方法的时候:

先找子类本身,再找父类。(就近原则)

final关键字修饰类,方法以及变量的特点(掌握)

A:final修饰特点

修饰类,类不能被继承

修饰变量,变量就变成了常量,只能被赋值一次

修饰方法,方法不能被重写

B:案例演示

final修饰特点

基本类型,是值不能被改变

引用类型,是地址值不能被改变,对象中的属性可以改变

多态

A 概述:事物存在的多种状态

B 多态前提

a:要有继承关系

b:要有方法重写

c:要有父类引用指向子类对象,比如Animal an=new Cat();//Cat类继承Animal类

C 访问成员变量和成员方法的区别

a 成员变量(无论是否静态):编译看左边(父类),运行看左边(父类),就是父类跟子类都有一个 int num,但多态中的话,

Father f=new Son();//Son继承Father,f.num是访问Father类里面的num

b 成员方法:编译看左边(父类),运行看右边(子类),就是子类Son重写了父类Father的方法show,父类 Father就会调用 show()方法调用子类的方法show(),这个也叫动态绑定

c 静态方法:编译看左边(父类),运行看左边(父类),其实这种相当于类名.方法

总结:只有非静态的成员方法才会动态绑定(编译看左边,运行看右边),像成员变量以及静态方法不会动态绑定 (编译看左边,运行看左边)

D 向上转型和向下转型

a 向上转型:父类引用指向子类对象,就是向上转型,比如Father father=new Son();

b 向下转型:前提必须有向上转型,比如Son s=(Son)father;//前提有Father father=new Son();

抽象类

abstract不可以和static,final,private等共用

* A 抽象类的成员特点

* a 成员变量:可以是变量也可以是常量,abstract不可以修饰成员变量

* b 构造方法:有(每个类都有一个默认的构造方法,无论类是否抽象)

* c 成员方法:可以是抽象方法(强制要求子类做的事情),也可以是非抽象方法的(子类继承的事情,提高代码的 复用性,可以重写)

B 面试题:一个抽象类如果没有抽象方法,可不可以定义为抽象类?如果可以,有什么意义呢?

可以,这样做的目的只有一个:那就是不让其他类创建本类对象,交给子类完成

接口的成员特定

A 成员变量:只能是常量,并且是静态的以及公共的.

* 默认修饰符:public static final

* 建议:自己手动给出

B 构造方法:接口没有构造方法

C 成员方法:只能是抽象方法

* 默认修饰符:public abstract

* 建议:自己手动给出

类于类,类与接口,接口与接口的关系

A 类于类:

继承关系,只能单继承,可以多层继承

B 类与接口:

实现关系:可以单实现,也可以多实现

并且还可以在继承一个类的同时实现多个接口

C 接口与接口(使用extends):

继承关系,可以单继承,也可以多继承

四种权限修饰符的测试(掌握)



内部类访问特点

a:内部类可以直接访问外部类的成员,包括私有。内部类之所以能获取到外部类的成员,是因为他能获取到外部类的引用外部类名.this

b:外部类要访问内部类的成员,必须创建对象。

外部类名.内部类名 对象名 = 外部类对象.内部类对象;(例如:Outer.Inner inner =new Outer(). new Inner();)

d:成员内部类被静态修饰后的访问方式是:

外部类名.内部类名 对象名 = 外部类名.内部类对象;例如(Outer.Inner inner =new Outer. Inner();),但注意new是属于Inner()那里的

(局部内部类访问局部变量的问题)(掌握)

局部内部类在访问他所在方法中的局部变量必须用final修饰,为什么?

因为当调用这个方法时,局部变量如果没有用final修饰,他的生命周期和方法的生命周期是一样的,当方法弹栈,这个局部变量也会消失,那么如果局部内部类对象还没有马上消失想用这个局部变量,就没有了,如果用final修饰会在类加载的时候进入常量池,即使方法弹栈,常量池的常量还在,也可以继续使用

但是jdk1.8取消了这个事情,所以我认为这是个bug

匿名内部类

A:前提:存在一个类或者接口

这里的类可以是具体类也可以是抽象类。

B:本质是什么呢?

是一个继承了该类或者实现了该接口的子类匿名对象。其实我个人感觉就是一个多态(向上转型),接着使用通过动态调用子类实现的方法

C:注意:

匿名内部类只针对重写一个方法时候使用

匿名内部类是不能向下转型的,因为没有子类类名

D:问题讨论

内部类(不是静态的)是否可以在外部类静态方法(外部类指的是包含内部类的那个类)中创建实例呢?如果不行,该如何修改才可以呢?

答:

1.内部类不可以在静态方法中创建实例或者调用内部类的静态方法,这里我个人认为应该把内部类看做一个属性(非静态的成员变量),非静态的成员变量是不可以在静态类中使用的;

2.如果你想使用,就需要在内部类前加上静态static,这样其实相当于Outer类跟内部类Inter是并行关系,以前内部类没有static的时候,内部类就可以看做是Outer的是一个非静态成员变量,不过内部类现在有了static,内部类Inter跟Outer是并行关系,不再是以前仅仅的从属关系了,代码如下:

PS:一句话讲完:非静态内部类Inter看做Outer类中的一个属性(非静态的成员变量,属于中国跟广东省的关系),但加静态内部类Inter跟Outer类就可以看成是中国跟香港的关系了,享有高度自治的特权)

3.非静态的内部类也不可以有静态方法(这个跟我们平时接触的类有点不同,因为我们平时接触的都是外部类)

public static void main(String[] args) {

new Outer.Inter().interPrint();//成了静态内部类之后,我就可以像香港一样,有自己的对外贸易规则
Outer.Inter.sinterPrint();//sinterPrint是静态方法,类名可以直接调用
new Outer().outerPrint();

}
}

class Outer {
//因为Inter已经成为了静态内部类,所以outPrint方法static不显得重要了(核心:内部类就相当于一个类中的一个特殊属性)
public static void outerPrint() {

Inter inter = new Inter();
inter.interPrint();
}

static class Inter {
public void interPrint() {
System.out.println("我是内部类");
}

public static void sinterPrint() {
System.out.println("我是匿名内部类的静态方法");
}
}
}


Eclipse工作空间的基本配置(掌握)

A:程序的编译和运行的环境配置(一般不改)

window – Preferences – Java

编译环境:Compiler 默认选中的就是最高版本。

运行环境:Installed JREs 默认会找你安装的那个JDK。建议配置了Java的环境变量。

问题:

低编译,高运行。可以。

高编译,低运行。不可以。

建议,编译和运行的版本一致。

B:如何去掉默认注释?

window – Preferences – Java – Code Style – Code Templates

选择你不想要的内容,通过右边Edit编辑。

注意:请只删除注释部分,不是注释部分的不要删除。

C:行号的显示和隐藏

显示:在代码区域的最左边的空白区域,右键 – Show Line Numbers即可。

隐藏:把上面的动作再做一次。

D:字体大小及颜色

a:Java代码区域的字体大小和颜色:

window – Preferences – General – Appearance – Colors And Fonts –Java修改 – Java Edit Text Font

b:控制台

window – Preferences – General – Appearance – Colors And Fonts – Debug – Console font

c:其他文件

window – Preferences – General – Appearance – Colors And Fonts – Basic – Text Font

E:窗体给弄乱了,怎么办?

window – Reset Perspective

F:控制台找不到了,怎么办?

Window–Show View—Console

G:取消悬浮提示

window – Preferences – Java–Editor–Hovers。右边将Combined Hover勾去掉。

这样代码的悬浮框就不会自动出现了。如果想看提示,将光标悬浮在代码上,按F2即可。

Eclipse中快捷键的使用(掌握)

A:新建 ctrl + n

B:格式化 ctrl+shift+f

C:导入包 ctrl+shift+o

D:注释 ctrl+/,ctrl+shift+/,ctrl+shift+\

E:代码上下移动 选中代码alt+上/下箭头

F:查看源码 选中类名(F3或者Ctrl+鼠标点击)

G:查找具体的类 ctrl + shift + t

H:查找具体类的具体方法 ctrl + o

I:给建议 ctrl+1,根据右边生成左边的数据类型,生成方法

J:删除代码 ctrl + d

K:抽取方法alt + shift + m

L:改名alt + shift + r

M:alt + shift + s 自动生成构造方法/自动生成get或set方法

==号和equals方法的区别(掌握)

==是一个比较运算符号,既可以比较基本数据类型,也可以比较引用数据类型,基本数据类型比较的是值,引用数据类型比较的是地址值

equals方法是一个方法,只能比较引用数据类型,所有的对象都会继承Object类中的方法,如果没有重写Object类中的equals方法,equals方法和==号比较引用数据类型无区别,重写后的equals方法比较的是对象中的属性

Scanner中注意事项

注意:Scanner中的nextLine()是键盘录入字符串的方法,可以接收任意类型,遇到\r\n(回车换行)符号就证明是一行,接着结束

解决办法:

* A 创建多一个Scanner对象来录入String类型(这种方法不太建议)

Scanner sc1 = new Scanner(System.in);
int i = sc1.nextInt();
Scanner sc2 = new Scanner(System.in);
String line = sc2.nextLine();


B 键盘录入的都是字符串,都用nextLine()方法接收,到时需要再转

String类



关于常量池的理解:Java常量池的大概理解 - 请叫我大师兄 - 博客频道 - CSDN.NET

String str="abc";//"abc"可以看成是一个字符串对象
str="def";  //String类为final类型,一旦复制就不能改变了,但String是类,可以改变引用地址,此时"abc"就变成了垃圾


A String类重写了toString方法,返回的是该类对象本身

B

//计算机把{97,98...}按照二进制存储起来了
byte[] bytes={97,98,99,100,101};
//接着解码(按照我们编辑器的码表来解码),把{97,98...}等解码出来
String string = new String(bytes);
//将bytes数组的下标2开始(数组从下标0开始),转2个出来
String string1 =new String(bytes, 2, 2);


C 面试题

第一题:判断下面定义为String类型的s1和s2是否相等?

//常量池没有这个字符串对象,就创建一个,如果有直接用即可
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2);   //true
System.out.println(s1.equals(s2));//true




第二题:以下这句话在内存中创建了多少个对象?

//"abc"就是一个String对象(在常量池中创建),接着new String对象(在堆内存中创建一个)
String s1=new String("abc");




API文档:String(String original) 初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。

第三题:判断下面定义为String类型的s1和s2是否相等?

//常量池没有这个字符串对象,就创建一个,如果有直接用即可
String s1 = "abc";//在常量池中
String s2 =new String("abc");//在堆内存中
System.out.println(s1 == s2);   //false
System.out.println(s1.equals(s2));//true


第四题:判断下面定义为String类型的s1和s2是否相等?

byte b1=3;
byte b2=4;
byte b3=b1+b2;//这里是变量里面的值相加,jvm无法知道里面的值是多少,所以可能会溢出的安全问题,所以需要强制
byte b4=3+4;//jvm有常量优化机制,在编译时候就变成了7,接着把7赋值给b4

String s1="a"+"b"+"c";//jvm常量优化机制,类似byte b4=3+4;
String s2="abc";
System.out.println(s1 == s2);   //true,常量优化机制
System.out.println(s1.equals(s2));//true


第五题:判断下面定义为String类型的s2和s3是否相等?

String s1="ab";
String s2="abc"; //在常量池中
String s3= s1+"c";//在堆内存中
System.out.println(s2 == s3);   //false
System.out.println(s2.equals(s3));//true




API文档:Java 语言提供对字符串串联符号(”+”)以及将其他对象转换为字符串的特殊支持。字符串串联是通过 StringBuilder(或 StringBuffer)类及其 append 方法实现的。字符串转换是通过 toString 方法实现的,该方法由 Object 类定义,并可被 Java 中的所有类继承。

关于Java常量机制详解的文章:Java常量池的大概理解 - 请叫我大师兄 - 博客频道 - CSDN.NET

String的重要方法



注意:

注意事项:

A “”跟null区别:

“”是字符串常量,同时也是一个String类的对象,既然是对象,当然可以使用String类的方法

null是空常量,不能调用任何的方法(要不然报NullPointerException),null常量可以给任意的引用数据类型赋值

B 使用equals方法时候注意:

String s1="woaini";
//如果是字符串常量和字符串变量相对,通常都是字符串常量调用方法,将变量当做参数传递,放置空指针异常
if ("admin".equals(s1)) {
System.out.println("字符匹配成功");
}


String类的转换功能



valueOf需要注意的是

//Person p=new Person()的时候,其实就是相当于String s=p.toString(),
//toString没有重写的话就是调用Object类的toString方法,输出的包名@哈希值
String s=String.valueOf(p)


concat(String str)方法调用的和传入的都必须是字符串类型

+可以让字符串与任意类型相加,更为强大

链式编程:只要保证每次调用完方法返回的是对象,就可以继续调用

首先计算机按照String转为二进制存储起来,接着getBytes转为byte类型(参考的码表与平台采用的码表有关)

String s1="你好你好";
byte[] bytes = s1.getBytes();//通过gbk码表将字符串转成字节数组
for (byte b : bytes) {       //编码:把我们看得懂的转为计算机看得懂的
System.out.print(b+"  ");//gbk码表代表一个中文两个字节==一个char
//-60  -29  -70  -61  -60  -29  -70  -61  //gbk代表特点,中文第一个字节肯定是负数
}


char转换都是参照Unicode码表(Java的编码是Unicode)

从字节与字符串互转肯定是gbk之类的,因为是io中是硬盘(存储以字节形式)到内存(字符串)的操作,那么就与系统有关,所以跟系统的编码有关系

String s1="你";
String s2="好";
int num1=s1.compareTo(s2);//20320-22909
System.out.println('你'+0);//20320,查找的是Unicode码表(Unicode包括ASCII码表)
System.out.println(s1+0);//你0
System.out.println('好'+0);//22909
System.out.println(num1);//-2589


[b]面试题:统计大串中小串出现的次数[/b]

渣渣算法:

// 需求:统计大串中小串出现的次数
//不管是黑马还是白马,主要跑得快,都是好马,虽然白马看起来比黑马弱小,但真正跑起来未必比黑马差
String max="buguanshiheimahaishibaima,zhiyaopaodekuai,doushihaoma,suirankanqilai,"
+ "baimabiheimaruoxiao,danzhenzhengpaoqilaibaimaweibibiheimacha";
String min="heima";

int count=0;//计算小串在大串中出现的次数
//判断小串是否在大串出现
if (max.contains(min)) {
//不需要到大串的最后一个索引
for (int i = 0; i <= max.length()-min.length(); i++) {
int index=0;
if ((index=max.indexOf(min))!=-1) {
count++;
max=max.substring(index+min.length());
}

}
}

System.out.println("heima出现的次数:"+count);


改进版算法:

// 需求:统计大串中小串出现的次数
//不管是黑马还是白马,主要跑得快,都是好马,虽然白马看起来比黑马弱小,但真正跑起来未必比黑马差
String max="buguanshiheimahaishibaima,zhiyaopaodekuai,doushihaoma,suirankanqilai,"
+ "baimabiheimaruoxiao,danzhenzhengpaoqilaibaimaweibibiheimacha";
String min="heima";//小串
int index=0;//索引位置
int count=0;//计算小串在大串中出现的次数
//indexOf找到就返回索引值,找不到就返回-1
while((index=max.indexOf(min))!=-1) {
count++;
//切割字符串,把统计入count的min(包括min)的字符串去除
max=max.substring(index+min.length());
}

System.out.println("heima出现的次数:"+count);

}


Java基础复习(二)链接:Java基础复习(二) - it菜鸟的飞行梦 - 博客频道 - CSDN.NET
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息