JAVASE 第二式


  • 拥有抽象方法的类叫做抽象类
  • 抽象类不能被实例化,但是有构造方法
  • 可以通过匿名内部类的方式表面看起来实例化(面试官会问)
  • 子类继承抽象类时,构造函数不会被覆盖。而且,在实例化子类对象时首先调用的是抽象类中的构造函数
  • 再调用子类中的。
  • 抽象类确实有构造方法,但这个构造方法是用来被子类调用的,因为任何子类都必须调用从Object开始的所有父亲的构造方法,才算完成初始化工作。如果抽象类被实例化,就会报错,编译无法通过。而接口里不包含构造器,自然无法被实例化。

局部变量必须要有初始值


Collection 接口常用的方法

  1. size():返回集合中元素的个数
  2. add(Object obj):向集合中添加一个元素
  3. addAll(Colletion coll):将形参coll包含的所有元素添加到当前集合中
  4. isEmpty():判断这个集合是否为空
  5. clear():清空集合元素
  6. contains(Object obj):判断集合中是否包含指定的obj元素
    ① 判断的依据:根据元素所在类的equals()方法进行判断
    ②明确:如果存入集合中的元素是自定义的类对象,要去:自定义类要重写equals()方法
  7. constainsAll(Collection coll):判断当前集合中是否包含coll的所有元素
  8. rentainAll(Collection coll):求当前集合与coll的共有集合,返回给当前集合
  9. remove(Object obj):删除集合中obj元素,若删除成功,返回ture否则
  10. removeAll(Collection coll):从当前集合中删除包含coll的元素
  11. equals(Object obj):判断集合中的所有元素 是否相同
  12. hashCode():返回集合的哈希值
  13. toArray(T[] a):将集合转化为数组
    ①如有参数,返回数组的运行时类型与指定数组的运行时类型相同。
  14. iterator():返回一个Iterator接口实现类的对象,进而实现集合的遍历。
  15. 数组转换为集合:Arrays.asList(数组)

关于反射

A Class类在java.lang包

B 动态代理技术可以动态创建一个代理对象,反射不行

C 反射访问私有成员时,Field调用setAccessible可解除访问符限制

D CGLIB实现了字节码修改,反射不行

E 反射会动态创建额外的对象,比如每个成员方法只有一个Method对象作为root,他不胡直接暴露给用户。调用时会返回一个Method的包装类

F 反射带来的效率问题主要是动态解析类,JVM没法对反射代码优化。


byte类型的变量在做运算时被会转换为int类型的值,故A、B左为byte,右为int,会报错;

而C、D语句中用的是a+=b的语句,此语句会将被赋值的变量自动强制转化为相对应的类型。


抽象类存在的意义就是在与被其他类继承,然后去实现其内部方法的,

区别 关键字abstract和关键字final

public abstract class Shape {
    public int width; // 几何图形的长
    public int height; // 几何图形的宽
    public Shape(int width, int height) {
        this.width = width;
        this.height = height;
    }
    public abstract double area(); // 定义抽象方法,计算面积
}
public class Square extends Shape {
    public Square(int width, int height) {
        super(width, height);
    }
    // 重写父类中的抽象方法,实现计算正方形面积的功能
    @Override
    public double area() {
        return width * height;
    }
}
public class Triangle extends Shape {
    public Triangle(int width, int height) {
        super(width, height);
    }
    // 重写父类中的抽象方法,实现计算三角形面积的功能
    @Override
    public double area() {
        return 0.5 * width * height;
    }
}
public class ShapeTest {
    public static void main(String[] args) {
        Square square = new Square(5, 4); // 创建正方形类对象
        System.out.println("正方形的面积为:" + square.area());
        Triangle triangle = new Triangle(2, 5); // 创建三角形类对象
        System.out.println("三角形的面积为:" + triangle.area());
    }
}

abstract用来修饰抽象类与抽象类中的方法

1.抽象类不能被实例化,抽象类可以包含属性、方法;构造方法,但是构造方法不能用来new实例,构造方法只能被子类调用

2.有抽象方法的类。一定是抽象类,但是抽象类可以没有抽象方法

3.当一个类继承的父类是抽象类的话。需要我们把抽象类中的所有抽象方法全部实现。除非子类也为抽象类

4.抽象方法不能有方法体

5.抽象类不能用final声明,因为抽象类只有被继承才有存在的意义,final修饰的类不可以被继承


final关键字
用来修饰类,类属性、类方法

注意:

1.被final修饰的类不能被继承

2.final修饰的类方法不能被重写,子类只有调用final方法的权利,没有修改final方法的权力

3.被final修饰的类属性只可在初始化赋值,不可被重新赋值

4.使用final修饰引用型变量,变量不可以指向另外的对象

class Dog {
    String name;
    public Dog(String name) {
        this.name = name;
    }
}
class Test {
    public static void main(String[] args) {
        final Dog dog = new Dog("欧欧");
        dog.name = "美美";
        dog = new Dog("亚亚");//此时这里会报错dog被final修饰,里面的地址不会改变
    }
}

JAVA中接口只能使用 public来修饰。接口内的方法默认为 public abstract


sleep()方法:抱锁睡觉

wait()方法:在其他线程调用notify对象或者notifyAll方法前。导致当前线程等待。线程会释放掉他所占有的锁标识。从而使别的线程有机会抢占锁

yield()方法:暂停当前正在执行的线程对象。该方法只是让当前线程重回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态马上又被执行
yield()方法只能使同优先级或者更高优先级的线程有执行的机会

join()方法等待该线程终止,等待调用join方法的线程结束,再继续执行,join的底层调用的wait(),故也会释放锁资源


当try块中包含return语句时候,在执行return语句前会先去执行finally块

1.finally{}代码块比return先执行。

2.多个return是按顺序执行的的,多个return执行了一个后,后面的return就不会执行了。

3.记住一点,不管有不有异常抛出,finally都会在return返回前执行。

try-catch-finally块的执行顺序:先去执行finally,若try中出现了异常则会调用catch()中寻找异常解决方法.


JSON语法的三种类型值:

1.简单值:使用与JS相同的语法,可以在JSON中表示字符串、数值、布尔值和null

2.对象:对象最为一种复杂的数据类型,表示的是一组有序的键值对。而每组键值对中的值可以是简单值也可以是复杂的数据类型

3.数组:数组也是一种复杂的数据类型,表示一组有序的值列表。可以通过数值索引来访问其中的值。数组的值也可以是任意类型


引用类型判断时,==判断的是地址是否相等。如果用常量字符串来定义的(如s1,s2,s4)会存在常量池里面;

用变量定义的就不会(如s3,s5)。所以上面的状态就是s1==s2;s4==“codercoder”;s3!=s4;s3!=s5。

String s3 = “coder”+s2 就不是存放在常量池中的


补充:JAVA内存结构

1.栈区:由编译器自动分配释放,具体方法执行结束后,系统会自动释放JVM内存资源

栈区的作用是保存局部变量的值如:用来保存基本数据类型的值、用来保存类的实例(即堆区对象的引用),也可以永安里保存加载方法时候的帧

2.堆区:一般由程序员分配释放,JVM会不定时去查看这个对象,如果没有引用指向这个对象就回收

堆区的作用是为用来存放动态产生的数据,包括new出来的实例、以及字符数组等

同一个类的对象拥有各自的成员变量,存储在各自的堆中,但是他们共享该类的方法

3.数据区:用来存放static定义的静态成员

4.常量池:JVM为每个已加载的类型维护一个常量池,常量池就是这个类型所用到的常量的一个有序集合,包括直接常量(基本类型和String)和对其他类型、方法、字段的符号引用,常量池中的数据和数组一样通过索引访问,由于常量池包含一个类型的所有对其他类型、方法、字段的符号引用,所以常量池早JAVA的动态链接中起到了核心作用。常量池存在于堆中。


static修饰的方法是存放在栈里面的,属于类的信息。因此不需要new对象就可以直接用类名调用static修饰的方法,而其他方法或者属性属于对象的,他们存在于堆中,因此需要new出某个类的对象才能引用




两同两小一大原则:

1.方法名相同、参数类型相同

2.子类返回类型小于等于父类方法返回类型

3.子类抛出异常小于等于父类抛出的异常

4.子类访问权限大于等于父类方法访问权限


抛出InterruptedException的代表方法有:

Java.lang.Object类的wait()

Java.lang.Thread类的sleep()

Java.lang.Thread类的join()


A:java异常和错误的基类是Throwable,包括Exception和Error

D:如果是等待清理队列中 如果有又被调用 则不会执行finalize方法

E:错在版本!


每次循环减2 i值永远不会等于0



关于抽象类:

JDK1.8之前,抽象类方法默认的访问权限是protected

JDK1.8时,抽象类方法默认的访问权限是default

关于接口:

JDK1.8之前,接口的中的方法默认的访问权限是public

JDK1.8时候,接口的中的方法默认的访问权限是public,也可以是default

JDK1.8之后,接口的中的方法默认的访问权限是private


start是开启线程。run是线程的执行体,run是线程执行的入口

start( )方法让thread进如可运行状态(runable) ,等待获取CPU的使用权限

CyclicBarrier(栅栏):让一组线程等待其他线程 (等待某个线程)

CountDownLatch(闭锁):让一组线程等待某个事件的发生 (等待某个事件)

Callable中的call方法比runnable中的run方法厉害之处就在于 call()可以有返回值并且可以抛出异常。

同时这个返回值和线程池一起用的时候可以返回一个异步对象Future。


结果集(ResultSet)的遍历 和 预编译 sql语句(prePareStatement)填充占位符都是从1开始编号的。


A: 存在脏读问题

B:CopyOnWrite()的核心是利用高并发往往 读多写少的特性,对读操作不加锁,对写操作,先复制一份新的集合 ,在新的集合上面修改,然后将新的集合赋值给旧的引用。

C: 分段加锁,只在影响读写的地方加锁,锁可以用读写锁,提高效率


实现多线程的三种方式,一种是继承Thread类使用此方式就不能在去继承其他类。还有两种分别是实现 Runnable接口或者去实现Callable接口


三元运算符会对两个结果的数据类型,进行自动的类型提升

Integer 会自动转成 Double( ),


Base base = new Son();这句new了一个派生类,赋值给基类。

所以下面操作编译器会认为base对象就是Base类型的 但是Base类中不存在 methodB( )方法,所以编译不通过


public static void main(String[] args){
    System.out.println(14^3)
}

^是表示异或,相同为0,不相同为1,需要转换成二进制进行运算!


Exception(异常):是程序本身可以处理的异常。主要包含RuntimeException等运行时异常和IOException

运行时异常:这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生,运行时异常的特点是JAVA编译器不会去检查它,即使没有try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过

非运行时异常(编译异常)包括:RuntimeException以外的异常,类型上都属于Exception类及子类,从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过


四种引用类型

JDK1.2 之前,一个对象只有“已被引用”和"未被引用"两种状态,这将无法描述某些特殊情况下的对象,比如,当内存充足时需要保留,而内存紧张时才需要被抛弃的一类对象。

所以在 JDK.1.2 之后,Java 对引用的概念进行了扩充,将引用分为了:强引用(Strong Reference)、软引用(Soft Reference)、弱引用(Weak Reference)、虚引用(Phantom Reference)4 种,这 4 种引用的强度依次减弱。

一,强引用

Object obj = newObject(); //只要obj还指向Object对象,Object对象就不会被回收 obj = null; //手动置null

只要强引用存在,垃圾回收器将永远不会回收被引用的对象,哪怕内存不足时,JVM也会直接抛出OutOfMemoryError,不会去回收。如果想中断强引用与对象之间的联系,可以显示的将强引用赋值为null,这样一来,JVM就可以适时的回收对象了

二,软引用

软引用是用来描述一些非必需但仍有用的对象。在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常。这种特性常常被用来实现缓存技术,比如网页缓存,图片缓存等。

在 JDK1.2 之后,用java.lang.ref.SoftReference类来表示软引用。

三,弱引用

弱引用的引用强度比软引用要更弱一些,无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收。在 JDK1.2 之后,用 java.lang.ref.WeakReference 来表示弱引用。

四,虚引用

虚引用是最弱的一种引用关系,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,它随时可能会被回收,在 JDK1.2 之后,用 PhantomReference 类来表示,通过查看这个类的源码,发现它只有一个构造函数和一个 get() 方法,而且它的 get() 方法仅仅是返回一个null,也就是说将永远无法通过虚引用来获取对象,虚引用必须要和 ReferenceQueue 引用队列一起使用。



for(条件1;条件2;条件3) {

//语句 }

执行顺序是条件1->条件2->语句->条件3->条件2->语句->条件3->条件2........ 如果条件2为true,则一直执行。如果条件2位false,则for循环结束


并不是多线程竞争问题,就是正常执行,先执行t.run();跑线程方法输出"pong",再执行打印语句"ping"
retrun "pongping"


监视器用来监视线程进入这个特别房间,他确保同一时间只能有一个线程可以访问特殊房间中的数据和代码。

JVM中没有进程的概念,但是JVM中的线程映射为操作系统中的进程,对应关系为1:1,在JVM中是使用监视器锁来实现不同线程之间的异步执行。在语法上的表现就是synchronized


抽象类可以定义普通成员变量而接口不可以但是抽象类和接口都可以定义静态成员变量

只是接口的静态成员变量要用static final public 来修饰


 

int y; 有默认值 0 答案是3


垃圾回收在 JVM中优先级相当低

垃圾收集器(GC)程序开发者只能推荐JVM进行回收,但是何时回收,回收哪些,程序员是不能控制的

垃圾回收机制只是回收不再使用的JVM内存,如果程序有严重的BUG,依旧会照成OOM

进入dead的线程,它还可以恢复,GC不会回收,宣布一个对象的真正死亡吗,至少需要经历2次标记过程,当第一次标记是会同时进行一次筛选(判断此对象是否有必要执行 finalize方法),如果对象没有覆盖该方法,就面临死亡,这个方法是对象逃脱死亡命运的最后一次机会



1. 只看尖括号里边的!!明确点和范围两个概念

2. 如果尖括号里的是一个类,那么尖括号里的就是一个点,比如List<A>,List<B>,List<Object>

3. 如果尖括号里面带有问号,那么代表一个范围,<? extends A> 代表小于等于A的范围,<? super A>代表大于等于A的范围,<?>代表全部范围

4. 尖括号里的所有点之间互相赋值都是错,除非是俩相同的点

5. 尖括号小范围赋值给大范围,对,大范围赋值给小范围,错。如果某点包含在某个范围里,那么可以赋值,否则,不能赋值

6. List<?>和List 是相等的,都代表最大范围

7.补充:List既是点也是范围,当表示范围时,表示最大范围

public static void main(String[] args) {
		List<A> a;
		List list;
		list = a;   //A对,因为List就是List<?>,代表最大的范围,A只是其中的一个点,肯定被包含在内
		List<B> b;
		a = b;      //B错,点之间不能相互赋值
		List<?> qm;
		List<Object> o;
		qm = o;     //C对,List<?>代表最大的范围,List<Object>只是一个点,肯定被包含在内
		List<D> d;
		List<? extends B> downB;
		downB = d;  //D对,List<? extends B>代表小于等于B的范围,List<D>是一个点,在其中
		List<?extends A> downA;
		a = downA;  //E错,范围不能赋值给点
		a = o;      //F错,List<Object>只是一个点
		downA = downB;  //G对,小于等于A的范围包含小于等于B的范围,因为B本来就比A小,B时A的子类嘛
	}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值