JAVA学习笔记

来源:互联网 发布:知圆链条索具 编辑:程序博客网 时间:2024/06/07 08:27

/************************/

方法重载:参数个数,类型,顺序。  不能根据返回值来判断。

This表示:方法的调用者对象的引用。

初始化顺序:变量优先于方法。对象也是变量啊。

静态变量优先于方法优先于普通变量

你引用的时候才会去初始化静态变量。不用。这个类就不初始化。静态变量不执行。

实际情况实际分析:变量优于方法,但是这个变量new出来给那个对象?他属于谁?有必要吗?

1.你将要执行这个类的main方法。所以你用到这个类了。需要先执行static变量初始化。

2.你将要执行这个类的main方法。所以你用到这个类了。但是里面没有static变量。有非static变量,此时将不会执行非static变量。原因很简单。你执行出来给谁。你又没有创建这个类的对象。你new出来的非static对象给谁?属于谁?说不清楚。

 

 

Final:1.定义final的时候就初始化。才是编译期常量。

Public final int a =rand.nextInt(33);这个就不是编译期常量。编译期你获取不到他的值。运行的时候才能获取。

引用前面加final。注意。意思是这个引用指向的地方不可变了。只能指向这个地方了。不能指向其他的地方了。但是指向的这个地方上面的值是可以改变的。注意。

定义一个空白的fianl 变量:public final int a;我可以不初始化,但是你必须在构造器里面初始化她。

 

继承关系终于搞懂了:

1.所有的东西都会继承下来。这个没有问题

2.Private的变量。会继承到子类中。只是没有写出来。但是:子类引用不到它,比如:子类对象.i  非法的。为什么?   因为他是private,权限范围只能在父类引用。只能在父类中a.i这样写;但是get/set方法是public的。我可以通过它访问。

Protected是包访问范围+子类访问。所以同一个包可以引用到: a.i。没有问题。

3.默认是只有包。你妈的。没有子类。区别好。

4.Private方法,也是继承下来了。但是它只能是在父类本类里面调用。所以子类调用不到。相当于就是final的。所以你再子类里面定义一个同名的private方法并不是覆盖。谈不上覆盖。因为你引用不到父类的private方法。所以这个方法是新的方法。你自己定义的。

5.在子类中调用父类的方法的时候,这个方法的执行上下文是什么?是父类的环境。

 

所以这样理解(验证是对的):

继承的时候,不要这样理解(东西全部继承下来了。这样不好理解。),应该是:子类可以调用这些父类的方法。是这个意思。然后子类调用的这些父类的方法的执行上下文是父类的环境。注意。注意父类的环境也要注意动态绑定,

 

多态与动态绑定:多态就是可以向上赋值,动态绑定就是你调用方法的时候他知道是调用之类的。注意:域没有动态绑定,静态方法也没有,知道意思吧。

 

接口里面的方法是默认是public的,但是实现类的时候,如果你不写public。默认是什么?包啦。域默认是static  finla的,在接口里面不能是空final,但是可以用rand之类的初始化。

 

抽象类继承抽象类。抽象类实现接口。接口继承接口。

字符串:

1.注意:在java里面,重载的运算符只有两个:一个是+,一个是+=。

1.String是不可变的。你每次调用+或者+=的时候实际上是编译器给你创建了一个stringbuilder,

所以如果你在循环里使用+,或者+=。特别注意。你不应该这样做。你应该自己先创建一个stringbuilder。

2.systm.out.println  systm.out.format

3.Format  a=new Format(system.out);

4.a.format(“%s  the trutle is at %d,%d is at (%d,%d)”, name , x, y);这样用的。

 

 

内部类:为什么需要内部类?解决多重继承的矛盾。不支持多继承,用内部类可以继承很多类。

1.费静态方法之外的任意位置。+main方法内部。创建内部类的对象。都要用  Class.innerClass  object 方式。

2.内部类里面可以访问外围类的所有的东西。私有的他也可以用

3.内部类对象是外围类对象创建的。内部类对象里面有个隐士引用,用来指向这个外围类对象。

4.怎么获取某一个内部类对象对外部类对象的引用。 可以在内部类里面写一个方法。这个方法返回一个外部类对象。里面是return  外部类.this;

5.外部类对象.new 内部类名字();  如果费静态方法之外。还要:外部类.内部类  a;

 

 

6.内部类在方法里面,或者在一个块里面。作用域为块。里面。方法外面或者块之外,不可访问。叫住:局部内部类。

7.匿名内部类:return   new   Paral(  ){  

如果无参数,说明调用的是默认的构造函数。无参数的构造函数。

如果有参数,比如说int  i;那么调用的是有参数的构造函数。

如果这个参数在{   }中用到了,那么的是:final  int  i  ,

              }

.8.静态内部类:内部类声明是static的。那么这个内部类的对象就没有对外部类的对象的引用了。

9.内部类还可以放在接口中,默认是public static的。。甚至你还可以实现这个接口。就是说这个内部类在某一个接口里面,然后这个类默认是public static的。然后还可以实现这个接口。。

10.可以继承内部类吗?可以的。内部类可以被覆盖吗?意思是你继承一个外部类,然后里面定义了一个与父类里面一样的内部类,只是这个内部类里面方法变了,那么这算覆盖吗?不算。运行的时候,不起什么作用,相当于说,这两个内部类是两个不同的实体。个人是个人的。

11.list set queue  继承collection   map里面有一个colletion,单独的。

List是按插入的顺序存储,不管是arraylist还是linklist。都是。

Set呢?不能有重复元素。Hashset是最快的  treeset比较结果的升序?   linkedhashiset .插入的顺序保存。任何时候hashset都是你的首选

Map呢?Hashmap那个最快   treemap比较结果的升序保存键 linkedhashmap插入顺序保存键

看那张图,里面不是有一个Listiterator。这个是专为list设计的,智能list使用。他可以前后移动,但是别的集合的只能向后移动。

Linklist还实现了queue接口,所以可以向上转型为queue,然后就可以用Queue queue  。queue.offer来出队进队

Priorityqueue优先级队列,默认是按照升序来排序的。是说每次弹出的是最大优先级的元素。那么优先级怎么定义?用你自己写的comparator来定义的。

 

New 任意集合<???>(任意集合,只要这个集合里面存的元素的类型跟???相同即可);

 

数组调用length的时候,是说这个数组能存储多少个数据,不是现在有多少个数据。注意。只是数组。

 

方法中传过来一个参数n,然后我   int a []=new int [n  ];这是可以的。

 

不能初始化参数化类型的数组比如  new  List <String > [10 ]   这个不允许。看清楚这是数组,平时我们是new  List < Stirng > ()

但是你可以这样。New List  [10]  然后强制转换成   Lsit <String>  abc [] 类型。

数组相等意思是说数组的元素个数相同,元素内容相同

。所以:int a[]=new int [10]  int b[]=new int b[10];这两个是一样的。A等于b。

数组或者容器,你存对象的时候,那么你存的是引用。注意啊。

 

注意:是谁实现这两个接口,是你要排序的元素啊,比如对象之类的。你对他排序啊,他们自己比啊。所以是元素实现这个接口。

排序实现comparable<   >接口,里面有一个compareto方法,你需要实现这个方法,比参数小返回-1,比参数大返回1.。这样的是升序。妈的坑爹。一直分不清。然后你创建了一个对象数组a。然后调用Arrays.sort(a)  自动升序,你

 

实现comparator<  T  >接口。里面有两个方法,一个是compare,一个是equeal方法,一般只实现compare方法,因为equeal默认从object继承。也是(T  O1,T   O2) O1小于O2返回-1是升序。也可以传入一个comparator接口。Arrays.sort(a,???) 这样子

 

只要是set,那么里面都是不可重复的集合。Set嘛。这句话要记住。

hash、tree的都要实现equeal方法,谁实现?元素实现。这句话是对的。

Linkhashset   hashset这两个必须实现hashcode方法   treeset不用实现hashcode,但是元素必须实现comparable接口。基本上就是所有的都要实现hashcode方法,tree的就不用,实现comparable或者comparator即可。

 

只要是map,那么就是说,都是<key,,value> 知道吧。这句话要理解记住。

Hashmap treemap linkhashmap  weakhashmap:key没有引用,那么这个<key,valuee将被回收。>

Hashmap判断key相不相同是按照equeal方法来判断的。先是用hashcode来找到bucket桶,然后每一个桶上面是一个linklist,然后再根据equeal来判断key。

所以自己写equeal方法的时候,请满足五个条件。

 

Object的equeal方法是比较地址的,地址一样返回true,不一样返回false。

默认的hashcode却是使用地址来计算散列吗的。注意。所以equeal方法没覆盖,那么算出来的hashcode值也不一样。

Hashcode就是把对象----int值,根据对象的一些信息来算。

 

 

 

 

1.Class对象。

2.Class类的class对象。就是说,每一个类都有一个class对象。Class.forname(“类的名字”);说明什么,说明这是Class类的静态方法。这个方法是干什么的,是获取class对象的。获取谁的class对象。当没有对象的时候用来获取class对象。直接通过类获取。Class对象还有很对静态方法。比如:cc.newInstance().直接通过class对象创建这个类的对象。屌不屌。但是是object的。需要转型。如果cc类型明确的话,就是说是某一个类的class对象。那么久不是object。是确切的这个class对应的类的对象。直接付给   类  abc=cc.newinstance();这个没有问题。如果cc是子类的class对象.getsuperclass()的来的,那么就是object。

3.如果你有类的对象后,那么a.getClass()来获取class对象。

4.还一种:类名.class。这只是一个引用,睡的引用个,class对象的应用。你写类名.class就相当于说这个引用指向了这个类的class对象了。

 

5.你类名.class。建引用。不会初始化这个类的。看前面第一页。

6.如果你取类里面的变量。这个变量是static  final的。那么可以不用初始化这个类的。注意

7.Class.forname...对象.getclass这些都要初始化这个类的。

8.int.class。float.class这些相当于就是说产生了INTEGER和FLOAT类的class对象了。

9.使用通配符: Class < ? >  intClass=int.class  这样子。然后 intClass=double.class;

10.子类的class对象.isInstance(父类);   


/************************/

1.非守护线程:就是你手动创建的线程。

2.Thread类里面有一些属性,id,name,priority属性,优先级属性,是1-10,其中1是最小优先级,10是最大优先级,一般不要修改优先级,当然你也可以改。Status属性,表示线程的状态,一共有六个线程状态。new,runnable,blocked,waiting,time waiting,terminaed

3.用runable来定义一个任务,实现runable,然后实现run方法,然后new一个runable对象,然后赋给thread类的对象构造器。在由这个thread对象启动atart方法。

4.callable的call方法,有返回值,用future<String>那么call方法就返回string类型。call方法返回什么,那么Future就是什么类型的<String>

5.thread对象t在别的线程的run方法里面调用 t.join方法.那么第二个线程要等待第一个线程执行完毕第二个才执行。

6.run里面的异常智能在里面捕获。在main里面捕获不到。用try catch没用的。

7.sychonized是隐寺的锁。lock是显示的锁。lock用在什么地方,就是说一些特殊情况的时候还是要用lock要灵活一些。比如。我想获取锁,但是没有获取到锁,那么我可以不用在哪里等。可以去做一些别的事情。那么这个情况就用lock,还有就是我想获取锁一段时间,比如10s,如果没获取到,那么就算了。不获取了。这个情况也要用lock。

但是如果你是synchonized的话,如果你没有获取到这个锁,那么你就要等待,啥也不能干。这就是lock与synchonized的区别。

8.每个对象都有一把锁,那么你用sychorinized的时候,你需要获取一把锁,那么获取哪个对象的锁呢?一般是this对象,就是你调用这个方法的对象的锁。你也可以指定别的对象。sychonized(对象名).获取这个对象的锁。只要这个对象的锁被sychonizend方法获取乐之后,就不能被其他synchonized方法获取了。

你可以new几个不同的对象。然后用sychonized来获取这几个对象的锁,然后就可以用两个线程同时去执行这两个synchonized方法了。因为是两把锁,个人是个人的。互不干扰。P47

9.ThreadLocal类。共享变量,多线程时候防止错乱,一人一份副本。

10.线程又四个状态,:new runable block dead。进入阻塞状态有几种情况:1.sleep,2.wait,3.等待io,4.想获取对象锁,但是锁被别的同步方法暂用。进入阻塞什么意思阻塞什么意思阻塞什么意思?阻塞的意思就是停在那里了,停在那里了。不执行了。停在那里了。停在那里了。

11.如果一个线程已经阻塞,或者正要阻塞,那么如果你调用interrupt方法,那么将会跑出异常,Interruptexception异常 ,中断状态将被复位,调用Thread.interrupted方法也会复位中断状态。复位的意思就是false,中断状态是false。

如果是执行器:Excutor调用shutdownnow,将会为每一个他启动的线程发一个interrupt方法,

12.I/o阻塞和synchonized阻塞不能被中断的。synchonized与lock的区别除了上面说的,还一个就是,lock阻塞的时候可以被中断。

13。sleep没有放锁,yeild也没有放锁(提建议,vm我已经做完事情了。你可以去做别的。)而,wait将会释放锁,如果你调用wait,那么这个对象的锁将被释放,

wait方法,notify方法,notifyall方法是基于object的,为什么??面试问你,你可以把这三个方法只能放到同步方法块(synchonized或者加锁的)里面

而不用考虑这个类是实现了runable还是继承了thread,因为是基于object的。   只能放到同步方法块里面。如果没放到同步块里面,编译没问题,运行会出问题。

14.实际情况中当你notify之后,有可能有多个任务想获取这个对象的锁。所以要用notifyall要保险一点。notify之后只有等待这个对象的锁的线程会被唤醒。就是说只有等待同一个锁的线程,如果有多个,那么他们会竞争,从中选择一个来获得锁。

15.还可以使用lock对象和condition对象。condition对象可以用来await多个任务,然后condition对象可以signallall所有这个condition挂起的任务,

注意。lock与condition,condition用来挂起一个任务,唤醒同一个condition挂起的所有的任务。

16BlockingQueue借口,有两个BlockQueue,一个是linkedBlockingQueue,一个是ArrayBlockingQueue,一个无界,一个有固定大小。

17.那些个同步容器,同步collection,的通用规则是:他们支持同事多个线程的读取和修改。背后怎么实现的?他是这样的,他修改的时候是在副本上修改,没有修改完之前,读的操作看不见。修改完之后与原数据交换,然后读的操作就可以看到了。都是这样的策略。

18.线程分组,线程组,Threadgroup类,同一组的线程你可以统一管理,比如统一interrupt。组内可以包含别的组。是个树形结构。P30。

19。怎么捕获线程组里面的非捕获异常。注意是非捕获异常。实现ThreadGroup里面的一个方法,即可捕获。

20.工厂模式,工厂类来创建线程。写一个类实现ThreadFactory类,然后实现newThread方法,这个方法需要一个runable参数,用来创建一个线程。

其实不难,就是说用一个工厂模式来创建线程而已。

21.还记得那个单利模式吗?synchonized关键字人家不是直接加在方法上,这样太费时间,应该加在尽可能少的代码上面。如果有的代码不用同步,呢么就不要用synchnoied括起来,同步很费事的。所以要用在刀刃上。

22.读写锁类:一共有两个锁,一个是读锁,一个是写锁,当获取读锁的时候,运行多个线程读。当获取写锁之后,只允许一个线程写。且别的线程不能读。

23.公平锁:lock读写锁的构造方法,你可以传入一个bool值,为true就是说是公平锁,每次选等时间最长的线程来执行。默认是false的。P65

24.

1 0
原创粉丝点击