【Java基础学习记录1】

发布于:2023-01-01 ⋅ 阅读:(576) ⋅ 点赞:(0)

--day001

代码规范:1.遇到左大括号要索引一个tab位置,相关性不强的代码建议空行;

 原码:

原码就是符号位加上真值的绝对值, 即用第一位表示符号,0为正,1为负, 其余位表示值. 比如如果是8位二进制:

[+1]原 = 0000 0001

[-1]原 = 1000 0001

第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:

[1111 1111 , 0111 1111]

[-127 , 127]

反码:正数的反码是其本身;负数的反码是是在其原码的基础上, 符号位不变,其余各个位取反.

[+1] = [00000001]原 = [00000001]反

[-1] = [10000001]原 = [11111110]反

补码:正数的补码就是其本身;负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

[+1] = [00000001]原 = [00000001]反 = [00000001]补

[-1] = [10000001]原 = [11111110]反 = [11111111]补

原码计算:1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2,结果显然不对,于是有了反码

反码计算:1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0,结果的真值部分是正确的. 而唯一的问题其实就出现在"0"这个特殊的数值上. 虽然人们理解上+0和-0是一样的, 但是0带符号是没有任何意义的. 而且会有[0000 0000]原和[1000 0000]原两个编码表示0.于是有了补码

补码计算:

1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]补 + [1111 1111]补 = [0000 0000]补=[0000 0000]原

这样0用[0000 0000]表示, 而以前出现问题的-0则不存在了.而且可以用[1000 0000]表示-128:

(-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]补 + [1000 0001]补 = [1000 0000]补

-1-127的结果应该是-128, 在用补码运算的结果中, [1000 0000]补 就是-128. 但是注意因为实际上是使用以前的-0的补码来表示-128, 所以-128并没有原码和反码表示.(对-128的补码表示[1000 0000]补算出来的原码是[0000 0000]原, 这是不正确的)

所以对于编程中常用到的32位int类型, 可以表示范围是: [-231, 231-1] 因为第一位表示的是符号位.而使用补码表示时又可以多保存一个最小值.

--day002

数据类型补充的小问题:

1.在定义Long或者float类型的变量时,结尾要加L或者f。

2.byte,short在定,他们接受的其实是一个int类型的值,这时自己做了一个数据检测,超过范围即报错。

3.byte值的问题:

byte占一个字节,取值范围-128~127

byte a =  (byte)128; //a = -128

byte b = (byte)129; //b = -127

byte c = (byte)130; //c = -126

结论:任意一个小范围的数据类型a去截取一个数据范围较大的数据类型b时,当达到a类型最大时,就会从头开始,即从最小值开始,如此循环。

128:10000000

-128::10000000(这里的1既是符号位,也是最高位),其实就是-0.

4.数据类型转换之默认转换

byte,short,char参与运算默认转换-->int-->{有long转换为)long-->(有float转换为)float-->(有double转换为)double

long:八个字节,float四个字节,为啥long排在float前面

原因:A:他们在底层的数据存储结构不同,float是科学计数法

           B:float表示的数据范围比long的范围大(long:-2^63~2^63, float:-3.4*10^38~3.4*10^38)

char:

 System.out.println('a')

 System.out.println('a'+1)

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

答:因为java中的字符char占两个字节,中文一个字符占两个字节。采用的是unicode编码。

6.java中任何数据类型和字符串拼接(+),结果都是字符串。但是注意运算数序。

 System.out.println(hello"+'a'+1)

 System.out.println('a'+1+"hello)

--day003

1.算术运算符中:整数相除只能得到整数,如果想得到小数,只需要把操作数据中的任意一数据变为浮点数。

2./获取的是除法的商,%获取的是除法的余数。

3.++,--的作用:对变量进行自增1或者自减1。

 A.单独使用放在变量前面和后面是一样的,推荐放在后面。

 B.参与运算使用时,放在操作数前面,先进行 自增或自减,在参与运算;

                                  放在操作数后面,先参与运算,在进行自增或者自减。

4.如果在程序中,可以使用括号改变改变优先顺序。

int x = 4;

int y = (x++)+(++x)+(x*10)

5.扩展赋值运算符其实隐含了一个强制类型转换。

shor s = 1; s = s +1;--->丢失精度

short t = 1; t += 1;--->正确,t += 1不是等价于 t = t + 1,而是等价于 t =(t的数据类型) + 1

6.比较运算符的结果总是boolean类型,等于==不能误写成=

int a = 10; int b = 20;

boolean flag = (a == b)-->正确,返回false

boolean flag = (a = b)-->错误,提示不兼容类型。//把b赋给a,把a留下来

7.逻辑运算符一般用于连接boolean类型的表达式或者值。

A.^逻辑异或,相同为false,不同为true。!

B.逻辑非,非false则true,非true则false,偶数个!不改变本身

8.重点&&和||,因为常用。

&&与&比较:

 1.执行结果一样;

 2.&&只要左边为false,后续都不执行,具有短路效果,执行效率高,&则是继续执行完

int a = 3;int b = 4;

int x = 3;int y = 4;

boolean b1 = ((a++) == (b++));

boolean b1 = ((++x) == (y++));

System.out.println("a:"+a);

System.out.println("b:"+b);

System.out.println("x:"+x);

System.out.println("y:"+y);

||与|比较:

 1.执行结果一样;

 2.||只要左边为true,后续都不执行,具有短路效果,执行效率高,|则是继续执行完

 4.位运算了解即可,但是是最接近计算机语言的。某个数据对另一个数据位异或两次,该数本身不变,可用作简单加密。

int a = 10; int b = 20;

System.out.println(a^b^b)//结果为10

System.out.println(a^b^a)//结果为20

 面试题:用四种方法实现两个整数变量的交换;

int a = 3; int b = 4;

方法A.

int tmp;

tmp = a;

a = b;

b= tmp;

方法B.

a = a ^ b

b = a ^ b;

b = c ^ b;

方法C.

a = a + b;

b = a - b;

a = a - b;

方法D.一句话搞定

b = (a + b) - (a = b);

9.<<:左移,右边补齐0-->大小等于左边的数乘以2的移动次幂

  >>:右移,最高位是0,左边补0;最高位是1,左边补齐1-->大小为左边的数据除以2的移动次幂;

 >>>:无符号右移,无论最高位是0还是1,左边补齐0,所以永远是正的。

 面试题:请用最有效的方式写出计算2*8的结果:2 << 3;

 10.三目运算符;(关系表达式)?表达式1:表达式2,关系表达式必须是boolean类型。

面试题:1.求两个数的最大值;2.求三个数的最大值;3.判断两个数是否相等;

int a = 10;int b = 20; int c = 30;

1.int max = (a>b)?a:b;

2.1分两步判断;2.2一步到位:int max1 = (a>b)?((a>c)?a:c):((b>c)?b:c);

3.1booean flag = (a == b)?true:false;3.2bolean flag1 = (a == b);//表达式本身返回的就是boolean类型

11.键盘录入:

import java.util.Scanner

Sacnner sc = new Scanner(System.in);

int x = sc.nextInt();

12.if语句注意事项

A.比较条件无论简单还是复杂,必须是boolean类型

B.if语句控制的语句体如果是一条,大括号可以省略,如果是多条就不可以省略,建议永远不要省略

int a = 100;

if(a == 100) 

  System.out.println("a等于10");

       System.out.println("over");//该条语句不会执行

C.一般来说有左大括号就没有分号,有分号就没有左大括号

int b = 100;

if(b !== 100);{   

  System.out.println("b等于10");

       System.out.println("over");//该条语句不会执行

 }//语句主体会继续执行,因为多了一个分号,就会认为if的语句体为空语句体。

13.if...else与三元运算符的异同

1.三元运算符可以做的if语句都能做,反之则不一定,都能做的建议用三元运算

2.当if语句输操作的是输出语句时,不可以用三元,因为三元运算符是一个运算符,运算符操作完应该有一个结果,而不是一个输出语句。

14.if ...else if...else:满足一个后续不执行,if语句的嵌套

--day004

比较几个固定的值建议用switch

 1.switch(表达式){

  case 值1:

    语句体;

    break;

  case 值2:

    语句体;

    break;

  ...

  default:

    语句体;

    break;

}

说明: 1.表达式的

是有限制的:byte,short,int,char;jdk5以后枚举可以;jdk7以后String可以;

             2.case是要和表达式进行比较的值,后面只能是常量,不能是变量,值不能相同;

             3.break表示中断,结束的意思。后面的就不执行了;

             4.都匹配,执行default;default可以省略但是不建议,因为他是处理错误情况,除非是固定值比较(单选题)。

    default不一定在最后,但是建议最后,但执行顺序是先走case;

             5.break可以省略,但是不建议,可能会出现case穿透现象。switch遇到break就结束或者走到最后结束。

 2.循环结构包括四部分:初始化语句;判断条件语句;循环体语句;控制条件语句。

 A.for循环循环如果是一句话,大括号可以省略,多条语句不可以省略,建议不省略

B.一般有左大括号没有分好,有分号没有左大括号。

涉及到连个思想:求和思想,求阶乘思想,统计思想

水仙花数:三位数x,各个位数的立方和等于本身。个位数:x%10;十位数:x/10%10;百位数:x/10/10%10,以此类推。

3.while循环和for循环是可以等价转换。如果想在循环结束后,继续使用控制条件的那个变量,使用while循环,否则用for循环。不知道则用for循环。因为变量急躁的从内中消失,可以提高内存的使用效率;

其实还有一种常见的理解:如果是一个范围,用for循环非常明确;如果不知道要做多少次,用while较为合适。

4.do...shile

初始化

do{

循环体;

控制条件语句;

}while(判断条件)

 区别:do...whilez至少执行一次循环体,而for,while循环需要先判断条件是否成立,然后决定执行循环体,一般顺序先考虑for循环,其次是while循环,最后do...while循环。

无论哪一种循环要注意控制条件,避免死循环。两种最简单的循环格式:

1.while (true) {

}

2.for( ; ; ){

}//这也说明三个参数不是必须都有

5.嵌套循环:外循环控制行数,内循环控制列数。

6.单引号加,'\x',x表示任意,这种做法叫转义:'\t':制表符,tab;'\n':换行;'\r':回车。

九九乘法表,结合5和6两点:

class JiuJiuBaio{

  public static void main(String[] args){

    for(int x=1; x<=9; x++){

      for(itn y=1; y<=x; y++){

        System.out.print(y + "*" + x +"=" + x*y + "\t")

        }

      System.out.println();

    }  

  }

}

7.跳转更关键子:goto目前不能使用,java中有break,continue和return来实现控制语句的跳转和中断。

break,中断:使用场景switch语句或者循环语句中加入了if判断情况。离开上面两个场景无意义。

class BreakDemo{

  public static void main(String[] args){

    break;//会报错,提示在switch或者loop外部中断

  }

}

 使用场景:1.跳出单层循环;

                     2.跳出多层循环,要实现这个功能,必须是使用标签,带标签的语句,格式如下

wc:for(int x=1; x<=9; x++){

      nc:for(itn y=1; y<=x; y++){

        if(y ==2){

          break nc;//跳出内层循环,内外层只能有一个

                                   break wc;//跳出外层循环

          }

        }

      System.out.println();

continue, 继续  ,循环中,离开此场景无意义。continue是跳出一次循环,继续下一次的循环                        

经典案例对比:

for(int x=0; x<10; x++){

  if(x%3==0){

  xxxx;

  }

  System.out.println("我爱java")'

}

1.输出2次我爱Java:xxxx=break

2.输出7次我爱java:xxxx=continue

3.输出13次我爱java:xxxx=System.out.println("我爱java")

 return:不是结束循环,而是结束方法的

 

 编程题目:

 

--day005

1.方法:完成特定工的代码块。格式:

                                                  修饰符 返回值类型 方法名(参数类型1 参数名1,参数类型2 参数名2...){

                方法体语句;

                                                        return 返回值;

}

详细解释:修饰符目前就用public static,后面再详细解释其他类型;

                  返回值类型:就是功能结果的数据类型;

                  方法名:符合明明规则即可,方便调用;

                  参数:

                         实际参数:具体实际参与运算的。

                         形式参数:就是方法定义的,用于接收实际参数。

                   参数类型:就是是参数的数据类型;

                   参数名:变量名

                    方法体语句:完成功能的代码。

                    return:结束方法的

                    返回值:就是功能的结果,由return带给调用者

方法最重要的是返回值和参数,所以要明确,方法不调用不执行,main方法是给虚拟机调用的。

如何调用:(有明确返回值的调用)

A:直接调用,一般来说没意义,不推荐

B:输出调用:但是不够好,因为我们需要对结果进行进一步的操作

C:赋值调用,推荐方案

方法注意事项:

    1.不调用不执行

    2.方法与方法是平级关系,不可以嵌套定义

    3.方法定义的时候参数用逗号隔开

    4.方法调用的时候不用传递数据类型

    5.如果方法幽冥取得返回值,一定要return带回一个值

2.方法调用void类型方法,void是没有明确返回值的类型,void空的意思。

如何调用:(无明确返回值的调用,比如打印语句

A:   直接调用,只能直接调用

B:输出调用:错误

C:赋值调用,错误

3.方法重载:方法功能相同,参数列表不同的情况,为了见名知意,java允许他们起一样的名字。jvm会根据不同的参数列表调用不同的功能

特点:在同一个类中,方法名相同,参数列表不同(个数或者类型),与返回值类型无关。

 

 

静态初始化推荐完整形式

 

 

 

 

 

 

 

 

 

排序和转置:

 

数组有关的自带方法:

 

 

 对象数组就是数组元素对象是类

 

 

 

 

 

 

4.数组:可以存储多个变量(元素)的东西(容器,集合),且变量的类型相同。可以存储基本数据类型,也可以存储引用数据类型。

定义格式:1.数据类型 [] 数组名--定义了一个某类型的数组xx变量,推荐

                  2.数据类型 数组名[] --定义了一个某类型的xx数组变量

初始化方式:为数组开辟内存空进,并未每个数组元素赋值

                     动态初始化:指定长度,由系统给出初始化值,int[] a = new int[3]//打印出来的是内存地址值,利用索引可以打印出具体元素的值,默认值为0

                      静态初始化:给出初始化值,由系统决定长度,常用 int[] a = {1,2,3}

5.java内存分类:

 

栈内存:

 栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中

1.对象实例化,声明的同时实例化:

 

 2.对象实例化,分步,先声明,再实例化:

 

 调用类的方法或者变量必须在对象实例化完成之后。

 类属于引用数据类型

 引用传递分析:简言之就是同一块堆内存空间可以被不同的栈内存所指向,也可以更换指向。

引用传递可以直接在主方法中定义,也可以通过方法实现引用传递处理,包括基本数据类型和引用数据类型

 

 引用于垃圾产生分析:

垃圾空间指的就是没有任何栈内存指向的堆内存空间,所有的垃圾都将被GC不定期回收,并且释放内存空间。但是如果垃圾过多,一定会影响到GC的处理性能,

从而降低整体的程序性能。所以开发中,垃圾越少越好。

一个栈内存只能保存一个堆内存地址,如果发生变更,则之前原有的地址数据将从栈内存中消失。

 栈内存的两个引用指向同一个堆内存的空间,无论是他们谁的操作,都是针对同一个地方。

数组常见的问题:

A.数组索引越界异常,访问了不存在的所以

B.空指针异常,数组已经不再指向堆内存了,而你还用去数组名访问元素。例如引用尅行的常量,arr = null,空常量null

6. 数组常见操作:

A.数组遍历:

B.获取数组中的最值

C.数组元素逆序,至少2种方法

D.数组查表法

E.数组元素查找(第一次出现的索引),此时要注意查找的数据如果不存在,注意要有返回值,只要是判断就可能是false,如果找不到数据,一般会返回一个负数,习惯是 -1.

 Foreach迭代输出:

--day006

二维数组:就是一个元素为一维数组的数组。二维数组了解即可,很少使用。

 数据类[][] 数组名 = new 数据类型[m][n]:m表示二维数组的元素个数,n表示二维数组的每个元素的元素个数

以下格式也是对的:

数据类型 数组名[][]  = new 数据类型[m][n]

数据类型[] 数组名[] = new 数据类型[m][n]

请问int[] x,y[]中x,y分别表示什么?x:一维数组,y:二维数组

int[][] arr = new iint[3][2];

System.out.println(arr);//地址值,含有两层[[

System.out.println(arr[0]);//输出元素的名称,地址值,含有一个[

System.out.println(arr[1]);//输出元素的名称,地址值,含有一个[

System.out.println(arr[0][0]);//0,int默认为0

null为引用类型的默认值

2.不规整的二维数组

数据类[][] 数组名 = new 数据类型[m][]:n不写,可以灵活赋予每个元素数组的元素个数。

int[][] arr = new iint[3][];//其中m必给,否则内存无法分配

arr[0] = new int[3];

arr[1] =new int[2];

3.格式三:静态初始化

数据类型[][] 数组名 = new 数据类型[][]{{元素1,元素2...},{元素1,元素2...}}

简化版:

数据类型[][] 数组名 = {{元素1,元素2...},{元素1,元素2,元素3...}},下图当所有的赋值操作完成后,才会把0x001地址值付给arr

 

 4.遍历二维数组元素:外循环控的二维数组的长度,内循环控制的是一维数组的长度。

 

 

 在java中只有值传递,实际值和地址值

A.基本类型,传递的是实际值,形式参数的改变对实际参数没有影响

B.引用类型,传递的是地址值,形式参数的的改变直接影响实际参数。

7.面向对象思想,万事万物皆对象

面向过程:项目小很方便,但是结构不清晰,不便于维护

 

 

 面向对象:项目复杂时采用,结构清晰,便于维护

 

 8.面向对象:开发,设计,特征

 

 事务与类

 

 

 8.构造对象,对象调用类的方法

 编译时,引用类内容时候会自动编译该类

 9.一个对象内存图,main方法最后消失

10.两个对象内存图,方法是一样的,所以重复利用,成员变量是所有对类的象都有的,但是变量值可能不一样,所以单独存放

11.三个对象内存图,演示两个变量引用指向同一个堆内存地址。打印对象名输出的是地址值

 

--day007

1.面向对象之成员变量和局部变量的区别

2.当一个方法的参数是类类型(引用类型)时,这里其实需要的是该类的对象。方法参数引用类型包含数组以及类。

3.匿名对象,就是没有名字的对象,有以下好处

--1.只调用一次,就将成为垃圾

-2.可以作为实际参数传递

4.类的封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式

 

 

 

 5.private,一般不修饰方法

 

 this关键字:

 

 

 

 

 

6.构造方法

 

 

 

 

 构造方法和构造方法都可以初始化数据,但是setter还可以更改数据。

构造方法首行

  1.构造方法可以调用普通方法,反之不行

简单java类:

 

 

 getInfo().

 

 

一般采用setXxx赋值,getXxx获取然后拼接

 7.创建对象做了哪些事情:调用构造方法时,首先为成员变量开辟内存空间并初始化

8.什么时候定义成员变量

9.static关键字,static修饰的变量是被所有对象引用

 

 

 

 

 

 

 

 

 

特点:

static修饰的变量只能在类中方法外

 static内存讲解:

10.static注意事项

11.静态变量和成员变量的区别

12.main方法详细解释

--day08

1.在同一个文件夹下。类定义在两个文件中和一个文件中是一样的。

2.制作说明书

 javadoc  (-encoding utf-8) -d  doc -author -version ArryTool.java

 3.查看帮助文档

4.代码块,

 

 

 

静态代码块主要是为static属性初始化

 

 

 

1.static代码块随着类的而加载一起加载
2.类在用得到的时候才会加载

9.继承 extends

 

 继承的特点:

 继承注意事项:

 

 

 10.this和super的区别:

11.继承中构造方法的关系:

 

 总结一下;

 

 12.继承中成员方法的关系:

 13.方法重写:子父类中,方法声名一样叫方法重写,包括名称和参数列表以及返回值

 方法重载注意事项:

 面试题:

 

 继承:进行代码重用,为了在已有的类上继续扩充类的功能

扩充更多

 

 

 

 

首行,所以不允许同时出现

 继承限制:

 

 

  方法重写:

 

   属性覆盖:

 

 

 

方法优先

 --day009

1.final

 

 

面试题目:

 

 2.多态

 可以没有方法重写,但是没有意义

 

多态的好处:

多态的弊端

 3.多态向上转型和向下转型:

 4.多态的理解以及成员变量的访问特点

A:向上转型:成员变量编译和运行都看左边;成员方法编译看左边,运行看最右边

A:向下转型:成员变量编译和运行都看左边;成员方法编译看左边,运行看最左边

5.多态继承内存图

 6.多态的访问特点:

 7.抽象类:abstract

 所以之前所得继承必须要重写父类的方法,指的是抽象类。多态主要用于抽象类。

抽象类的成员特点:

 8.抽象类中方法的小问题:

    1.一个类如果没有抽象方法,可以定义为抽象类吗?有何意义?

    可以,不让创建对象,也就是可以通过该类创建对象

    2.abstract与private,final和static搭配,什么问题?

    private:会冲突,因为private修饰的方法不可以被继承,不被继承就无法重写,abstract修饰的方法就是要重写

    final:冲突,final修饰的方法不可以被重写

    static:无意义,因为static是可以直接被类调用的,但是abstract没有方法体,所以调用没意义

 9.接口,interface

 10.接口的成员特点:

11.面向对象(类与类,类与接口,接口与接口的关系):描述类的关系是单继承,但是接口是可以多继承的

 

 12抽象类和接口的区别:

 --day010

方法递归调用:解决一些麻烦的事情

 

 递归不建议私用,一般是由系统提供,还容易造成内存溢出(方法栈溢出)

 求阶乘:

 

 --Day011

1.数据表与简单Java类映射转换,包含一对多,多对多,复杂映射。

 先写出基本类,在设置关系,最后根据需求进行调用。

2.字符串

JVM致辞的制造的一种可以简单使用的String类

 

 

 

 

 

 

 3.字符串比较

  1.  ==是判断两个变量或实例是不是指向同一个内存空间,equals是判断两个变量或实例所指向的内存空间的值是不是相同 
  2. ==是指对内存地址进行比较 , equals()是对字符串的内容进行比较
  3. ==指引用是否相同, equals()指的是值是否相同
  4.  

 

equals与==的区别详解:

        == 比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。比较的是真正意义上的指针操作。equals用来比较的是两个对象的内容是否相等,由于所有的类都是继承自java.lang.Object类的,所以适用于所有对象,如果没有对该方法进行覆盖的话,调用的仍然是Object类中的方法,而Object中的equals方法返回的却是==的判断。String s="abcd"是一种非常特殊的形式,和new 有本质的区别。它是java中唯一不需要new 就可以产生对象的途径。以String s="abcd";形式赋值在java中叫直接量,它是在常量池中而不是象new一样放在压缩堆中。 这种形式的字符串,在JVM内部发生字符串拘留,即当声明这样的一个字符串后,JVM会在常量池中先查找有有没有一个值为"abcd"的对象,如果有,就会把它赋给当前引用.即原来那个引用和现在这个引用指点向了同一对象, 如果没有,则在常量池中新创建一个"abcd",下一次如果有String s1 = "abcd";又会将s1指向"abcd"这个对象,即以这形式声明的字符串,只要值相等,任何多个引用都指向同一对象.
   而String s = new String("abcd");和其它任何对象一样.每调用一次就产生一个对象,只要它们调用。
也可以这么理解: String str = "hello"; 先在内存中找是不是有"hello"这个对象,如果有,就让str指向那个"hello".

如果内存里没有"hello",就创建一个新的对象保存"hello". String str=new String ("hello") 就是不管内存里是不是已经有"hello"这个对象,都新建一个对象保存"hello"。

 在JVM的底层实际上会自动维护一个对象池(现在是字符串对象池),如果采用直接赋值的模式进行String类对象的实例化操作,那么该实例化对象(字符串内容)将自动的保存到这个对象池之中,如果下次继续 有人使用了直接赋值的模式声明了String类的对象,那么如果此时对象池之中由指定的内容,那么将直接进行引用,如果没有,则开辟新的字符串对象,而后将其保存在对象池之中,以供下次使用。(所谓的对象池就是一个对象数组)

第一种:直接赋值

   String str =  "hello!" ;

在java中,有一个字符串常量池,对于这种直接赋值的,会直接写进常量池(常量池里面不存在其value,)

自JDK1.7后,常量池也属于堆内存,为了实现数据共享;

所谓的直接赋值,描述的是将一个匿名对象设置一个具体的引用名字

第二种:构造方法

   String str = new String("hello!");

这样会开辟两块堆内存,第一块是由“hello!”这个匿名对象开辟,第二块是new开辟

首先会检查常量池里面是否存在“hello!”,如果不存在,则在常量池开辟一空间,然后new出来的String实例,也会在堆内存开辟空间

一般是使用new开辟的那一块空间,而字符串常量池那块内存,将会成为垃圾空间

 4.字符串池

 

 

 

 

 

5.字符串修改

String类对于数据的存储是基于数组是实现的,一旦声明不能改变,而所有的 字符对象内容的修改都是通过引用的变化来实现的。

对字符串对象内容修改,其实质是改变了引用关系,同时会产生垃圾空间。

 java主方法组成分析:

 

 5.字符串与字符(数组)

 

 小写字符编码减32变成大写

字符比较大小,是比较ascii码值

重要方法:

 用途:可以判断一个字符串是不是有纯数字组成

  5.字符串与字节(数组)

 

 重要方法:

 6.字符串比较,compareto比较的是字符串的大小值,返回的是int类型的结果

 7.字符串查找

 

 indexOf 方法返回一个整数值,指出 String 对象内子字符串的开始位置。如果没有找到子字符串,则返回-1

 indexOf 方法返回一个整数值,指出 String 对象内子字符串的开始位置。如果没有找到子字符串,则返回-1。
如果 startindex 是负数,则 startindex 被当作零。如果它比最大的字符位置索引还大,则它被当作最大的可能索引

 7.字符串替换,难点在于正则匹配表达式

 8.字符串拆分

,后面的不拆

 9.字符串截取

 

 9.字符串格式化,静态方法

 

10.字符串其他方法

 concat的连接并不是静态连接,而是编译连接,不同有 “+” 连接符

trim只能去去除前后空格

 但是String没有提供将字符串首字母转换为大写的方法

 --Day--012

Annotation简介

jdk1.5后,

 

 

 

 

 

 

 

 编译时会提示使用活覆盖已过时的API。

 

 

,能够压制多种告警

 

多态性:

 

 

 

 向上转型注意点:看实例化的是哪一个子类,并且子类有没有进行方法重写,如果有调用的就是子类的方法。向上转型是最常用的方法。

 

 

 

 

 

 

  --Day--013 object类

 

 

 

 

 

 

 

 

 对象比较比较的是两个是对象的内容是否完全相同,而不用的对象有不同的地址,所以此时比较应该是通过内容来完成。

 两个数字之间的比较我们使用“==”,两个字符串之间的比较我们使用“equals()”,那么两个对象之间如何进行比较呢?既然要进行两个对象之间的比较,那么就必须要实现两个对象之间所有属性内容的比较。

getter方法。

 

 

 注意点:

 

 

 

 抽象类模板设计模式:

 

 

包装类:

基本数据类型并不是包装类,而如果

 

 

 

类型来接收。

包装类:

 

Double

Number类是个抽象类,记住其中的6个方法

 

6种

 装箱和拆箱:

,也可以使用静态方法valueof()完成。一般建议使用valueOf。new每次都会创建一个新对象,而除了Float和Double外的其他包装类,都会缓存包装类对象,减少需要创建对象的次数,节省空间,提升性能,后续我们会分析其具体代码。

 

注意: 

 

 

 自动装箱/拆箱是Java编译器提供的能力,背后,它会替换为调用对应的valueOf()/xxxValue()

 

 

包装类的相等判断:

接口:

 

 

 

含有抽象方法:

子类实现多个父接口:

 

 

 

 

 

1.

 

 

2.

.

 ,实现多继承的接口是时,需要重写所有的相关接口的方法。

接口定义加强:

 

 

 

方法

 

  

口直接调用

接口定义标准:

 

 

 不同类型之前是通过接口实现的,不关系类型只关心接口的标准。

工厂设计模式:

 工厂模式:主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化哪一个类,从而隐藏具体实现的子类。

优点:

工厂模式是为了解耦:把对象的创建和使用的过程分开。就是Class A 想调用Class B,那么只是调用B的方法,而至于B的实例化,就交给工厂类。

工厂模式可以降低代码重复。如果创建B过程都很复杂,需要一定的代码量,而且很多地方都要用到,那么就会有很多的重复代码。可以把这些创建对象B的代码放到工厂里统一管理。既减少了重复代码,也方便以后对B的维护。

工厂模式可以减少错误,因为工厂管理了对象的创建逻辑,使用者不需要知道具体的创建过程,只管使用即可,减少了使用者因为创建逻辑导致的错误。

缺点;

  1. 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响。
  2. 要新增产品类的时候,就要修改工厂类的代码,违反了开放封闭原则(对扩展的开放,对修改的关闭)。
  3. 简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构

代理设计模式:

代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。

静态代理:

优点:静态代理实现了公共业务和真实的业务逻辑的分离,降低了耦合,结构更清晰,维护更方便,扩展更容易,分工更明确。

缺点:代码的复杂程度增加,每个业务类都需要有一个相关的代理类,代码量增加-------解决办法:使用动态代理

动态代理:

动态代理解决了静态代理的缺点;一个类可以代理多个真实对象

 抽象类与接口的区别:

 

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw== 编辑


网站公告

今日签到

点亮在社区的每一天
去签到