Java基础回顾(面试)

在这里插入图片描述

八种基本类型

long 8字节 int 4字节 short 2 字节 byte 1 字节
boolean 4字节 double 8字节 float 4字节
char (根据编码 ASCII 码 1字节 Unicode 2字节 )

根据八种基本类型引出 float和int 的精度问题

越近0精度越高(大于int) 离0越远精度低 (低与int)

根据int引出128陷阱

-127 ------ 128 如数字没超过这个范围存在同一个对象中,超过那么就要重新创建一个对象(新开辟一个空间)

引出包装类

Integer包装类 将int变成对象 类型之间的转化,数据类型之间的基本操作(自己写工作量大),基本类型并不具有对象的性质,为了让基本类型也具有对象的特征,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。

String类型

  • string不可变,是指原地址不可变(可能修改后的字符串在原地址存不下,需要换地址存,所以不能在原地值上修改,即不可变)
  • 实现:string类是被final修饰 并且string得char数组也是被final修饰并且类中并没有提供修改值的方法
  • StringBuffer和StringBulider,都是字符串拼接,也可以用+号拼接,不是字符串不可变吗?那为什么可以,因为final可以控制住简单对象,复杂对象数组控不住。StringBuffer是线程安全的,可以用在多线程,StringBulider则不安全。StringBuffer是有缓冲区的,StringBulider则是直接复制。因为StringBuffer它的所有公开方法都是同步的所以性能没有StringBulider好;
  • 字符串常量池在1.7前是在方法区中,之后是在堆中;

final/finally/finalize

final

  • 修饰类,最终类,不可以被继承
  • 修饰变量,必须初始化,不可以被修改
  • 修饰方法,最终方法,不可以被重写
  • 防止指令重排序,保证线程可见性(面试点)

finally

  • 在异常体系出现,在程序进入try块之后,无论程序是因为异常而中止或其它方式返回终止的,finally块的内容一定会被执行 。

finalize

  • 对象析构,保证对象在被垃圾收集前完成特定资源的回收

static

  • static 静态声明的直接在方法区有自己独立地址内存 可以直接被调用静态的属于类,只有一个,只要有static所有线程都可见可读
  • 静态不能调用非静态的方法(可以new后再调用),但非静态可以调用静态,(因为静态是属于类的优先级高,非静态是在之后出来的。)
  • 能不能在main方法内写static int a =3;? 不能

为什么重写equals()就一定要重写hashCode()方法

  • 仅仅使用equals()方法的话,集合规模的增大,时间开销是很大的,使用哈希表的话,就能快速定位到对象的大概存储位置,并且在定位到大概存储位置后,后续比较过程中,如果两个对象的hashCode不相同,也不再需要调用equals()方法,从而大大减少了equals()比较次数

      两个对象的equals相等,则hashcode一定相等
      两个对象的hashcode相等,则equals不一定相等
    

==和equals()的区别

  • == 判断基本数据类型是否相等(引用数据判断地址是否相同)
  • 用 equals 方法检测两个字符串是否相等

封装,继承,多态

封装:封装将属性私有化,提供对外的get set方法让其方访问
继承:一旦子类继承父类,要先在方法区加载父类的代码模板,在加载子类的(static,一new就加载) 单继承 但可以多级继承,子类继承父类所有方法(但是私有属性虽然继承但是无法访问)
多态:多态是同一个行为具有多个不同表现形式或形态的能力。
实现: 1.子类必须继承父类 2.必须重写父类方法 3.父类引用子类对象(子类伪装父类,只能用父类方法,但是实质是调用子类重写的方法;)

重写和重载

重写:同名同参;返回值范围和异常抛出小于父类,访问修饰符要大于父类。
重载:同名不同参,参数不能同类型,因为无法分别,和返回类型无关,可同可不同(例子:多个构造器)为了简化方法名;发生在编译的时候;

抽象类和接口

1.接口的方法默认是 public,所有方法都是抽象方法,在接口中不能有实现(Java 8 开始接口方法可以有默认实现,使用default关键字),抽象类可以有非抽象的方法
2.接口中的实例变量默认是 final 类型的,而抽象类中则不一定
3.一个类可以实现多个接口,但最多只能继承一个抽象类
4.一个类实现接口的话要实现接口的所有方法,而抽象类不一定
5.接口不能用 new 实例化,但可以声明,但是必须引用一个实现该接口的对象 从设计层面来说,
6.抽象方法不能使用static,static是针对类层次,抽象方法是针对对象层次的,所以不能一起使用.
抽象类是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。

反射,获取类对象方式

反射:jvm得到类对象之后,反编译,得到对象信息(能够分析类信息的能力叫反射)
获取类对象方式:

  • Class.forName(“具体包名.类名”);
  • 类.class 有类时用这个
  • 对象.getClass(); 有对象时用这个

忽略安全访问修饰符的安全检查 setAccessible(true) //暴力反射

例子
tomact中利用反射
通过class.forName进行反射 ,通过注解把servlet挑出来,获取注解值

静态的全局变量HashMap 注解值(servlet路径)作为key newinstance获取的对象作为value

代理

代理的目的:通过代理业务对原有业务进行增强,防止直接访问目标对象给系统带来不必要的复杂性
分为:静态代理 JDK代理 CJLLIB代理

静态代理:中间代理,提供一个中间接口,实现目标的接口或者直接继承目标类,完成逻辑的修改

JDK代理:只提供接口的代理,不支持类的代理。核心InvocationHandler接口和Proxy类,InvocationHandler通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起;Proxy利用InvocationHandler动态创建一个符合某一接口的的实例, 生成目标类的代理对象。

CJLLIB代理:没有实现 InvocationHandler 接口,是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

异常体系

Thorwable类(表示可抛出)是所有异常和错误的超类,两个直接子类为Error和Exception,分别表示错误和异常。

运行时异常和非运行时异常:

  • 运行时异常都是RuntimeException类及其子类异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生
  • 非运行时异常是RuntimeException以外的异常,从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常。

throws和throw的区别

- 使用throws关键字声明的方法表示此方法不处理异常,**而交给方法调用处进行处理。**

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值