笔记-java基础

313 阅读16分钟
  • 1.System.out.print/printIn区别
    printIn换行

  • 2.类与对象
    1.父类比较抽象,子类具体,子类自动获得父类方法。也可以覆盖(子类重新定义继承下来的方法,以改变或者延伸此方法行为)。

    2.类:实例变量+方法

    3.类不是对象,类是用来创建对象的模型

  • 3.变量
    1.变量有两种:primitive主数据类型和引用。

    2.存数字的:primitive主数据类型有8种:byte 8位(-128~127)、short 16位、int 32位、long 64位(四个一组)-----以及 float 32位、double 64位------以及 boolean和char 16位(0-65535)

    3.大装小 可行(short b=1;int a=b)。小装大 不行(int b=1;short a=b不行)。小杯子不可以装大杯子的东西(得强转)。大杯子能装小杯子的东西,但是会丢失精度。float可以转double ----- double不可以转成float,得double转String转float
    示例:new BigDecimal(String.valueOf(double a)).floatValue()
    示例:int a=1; long x=a;(通过编译)
    示例:long a=1; int x=a;(无法通过编译) int x=(int) a;(可以通过)编译器把值裁成int

    4.实际上没有对象变量,只有引用到对象的变量。类似于指针。
    Dog myDog=new Dog(); 虚拟机分配空间给myDog引用变量并定类型为Dog。用该引用变量来控制堆上面的Dog对象。等于就是连接引用变量和对象。----所以myDog只是一个指针(引用)不是实际对象

5.如果对象没有引用,在堆上就会被回收。Dog myDog=new Dog(); myDog=null;--- new Dog()就会被回收

6.数组---Dog[] pets=new Dog[7]; pets[0]=new Dog(); pets[1]=new Dog();------各个关系见下图。

  • 4.方法与实例变量

    1. 实例变量就是声明在类中的变量(全局变量)(都有默认值),局部变量是方法中的变量(没有默认值)。
    2. 实例变量都会有默认值。int char等为0,booleans为false,对象的引用为null。null代表没有操作的对象,null是引用不是对象。
    3. ==和equals()。 ==用来判断是否引用的是一个对象。equals()判断两个对象是否在意义上相等。 主数据类型直接用==就行。
    4. X++与++X X++先运算在++,++X先++在运算。 x=0;z=x++; z=0,x=1;
    5. hashCode()与equals()。hashCode是用来缩小查找成本的,equals才是真相等。两个对象相等则hashCode相等。hashCode相等值不一定相等。
  • 5.Java的API

    1. ArrayList不是数组是java函数库中的一个类,List是实现它的一个接口。remove(Object elem) 如果和对象参数匹配返回ture//indexOf(Object elem) 返回对象参数索引或-1,元素位置position//isEmpty() 是否有值
    2. ArrayList与数组。①数组初始化得指定大小。new String[2]②ArrayList得指定类型List
  • 6.继承和多态
    1.继承:子类继承了父类public的实例变量和方法(不继承privite)。子类可以覆盖父类方法。

    2.继承意义:①避免了重复的程序代码②定义出共同的协议(继承确保某个父类之下所有类都会有父类所持有的全部方法)。

    3.多态:引用类型可以是实际对象类的父类。

    Animal a=new Dog();  
    Animal[] animal=new Animal[2];  
    animal[0]=new Dog();  
    animal[1]=new Cat();  
    animal[0].eat();animal[1].eat();  分别调用了猫的吃和狗的吃。  
    privite void chi(Animal animal){
    animal.eat();
    }  
    

    chi(cat);chi(dog); 可以执行,只要是子类就行,分别调用了猫的吃和狗的吃。

    4.继承层级,没有限制,一般不会很深,2层左右,继承树少一点合理。

    5.类不被继承情况:①存取控制,类只有public或者不声明的情况。不声明时class A{}只能被同一个包的继承。②final,final表示它是继承树的末端不能被继承。③让类只拥有privite的构造程序

    6.finial 标记类表示类不能被继承(所有方法不能被覆盖),标记方法表示方法不能被覆盖。

    7.覆盖规则:①参数必须要一样,返回值兼容。(返回值一样或者子类)②不能降低方法的存取权限(public privite)

    8.方法的重载:方法名相同,参数不同★只跟参数有关。①返回类型可以不同,只跟参数有关②可以更改存取权限(public privite)。③跟继承多态等等无关。

    9.抽象-abstract。抽象类不能被new(不能被初始化),不能创建出该类的实例,但可以被继承。抽象类除了被继承过之外,是没有用途,没有值,没有目的的。----为什么要有抽象?new Animal();我们不知道Animal长什么样,只有一些共有的特效,所以得防止Animal被创建,得抽象,让子类继承成具体的类。

    10.抽象与具体。不是抽象的类就叫具体类。 一个继承树,动物、哺乳类、灵长类 应该声明为抽象类 人类,金丝猴应该声明为具体类。

    11.抽象方法。抽象方法代表此类必须要被继承,子类也必须被覆盖(必须实现所有抽象方法)。抽象方法必须类也抽象。
    用途:BaseActivity: public abstract void initView(); ★ 没有具体方法,只声明一个名就行 直接用;

    12.抽象的好处:就是多态。多态的好处就是所有子类都会有那些抽象方法。想要使用父类作为方法参数、返回类型或数组类型。

    13.抽象方法没有内容,它只是为了标记出多态的存在。这表示在继承树结构下的第一个具体类必须要实现所有的抽象方法。也就是说只要声明abstract就可以不必实现父类的抽象方法,让子类去一起实现父类的抽象方法。

    14.Object。①equals(Object o)②getClass() 初始化对象是什么-什么类型的③hashCode()返回唯一哈希ID④toString()。

    15.编译器只管引用的类型不管对象的类型。 当把Dog放到Object上时,就变成了Object类型不再是Dog类型。
    Object o=new Dog(); o不能执行Dog的方法。如果要转回Dog得强转。Dog d=(Dog)o;★★★强转之前得判断类型 instanceof 。 if(o instanceof Dog) Dog d=(Dog)o;

    16.interface接口。---全部方法是公有的,抽象的。自带public+abstract。

    17.接口是对事物属性和行为的更高层次的抽象,对修改封闭,对扩展开发。

    18.super调用父类方法。

  • 7.构造器与垃圾收集器
    1.程序员关心内存区域:堆栈。堆:存放所有的对象。栈:方法和局部变量。 Dog a=new Dog(); a.getA(111); a引用,getA()方法,111局部变量都在栈上(堆栈块中)。 new Dog()对象在堆上。

    2.局部变量是在栈上的。那么实例变量呢?实例变量是在堆上的。 实例变量是存在所处的对象上的,对象是在堆上的。所以实例变量是在他的对象的堆上的。

    3.构造函数。唯一能够调用构造函数的方法就是新建一个类,也就是new。 Dog a=new Dog();其实是调用了Dog类中的构造函数(无参数而已),默认自带一个无参数的构造函数,自己重写以后,无参数构造函数就被没了。构造函数的参数得不一样(类型和顺序)只要一个不一样就行。

    4.构造函数名必须与类同名,并且没有返回类型。在创建新对象时,所有继承下来的构造函数都会执行-父类的所有构造函数都会被执行。 因为子类可能会调用super或根据父类的状态来继承方法。

    5.构造函数在执行的时候第一件事就是执行其父类的构造函数,直到最顶层Object为止。 这个过程被称为构造函数链。---小孩得在父亲出生后出生。

    6.super()调用父构造函数,用this()调用自己的构造函数,this()只能在构造函数中,且得是第一句。this()和super()只能二选一。

    7.对象的生命周期取决于它的引用,没有引用的对象就会变成可回收状态。可能情况:引用指向别的对象;=null;引用离开了范围。

  • 8.数字与静态
    1.静态static关键词可以标记出不需要实例的方法。----->没有对象/不能new/不能初始化 自己理解:静态,静止状态。全局的跟其他所有的类都是共享的,不会因为变量或者其他影响。像工具,大多数工具、方法都是静态。

    2.静态的作用:比如Math.min(1,100);Math.min()方法,只负责比较传入两个值的大小,跟Math类中的其他方法没有关系,跟Math类中的实例变量没有关系,所以可以生命成静态static。这样调用的时候可以直接调用Math.min()该方法,不必先new Math,创建Math对象浪费空间。------所以在一些工具类,工具方法中可以生命静态,比如取时间,转换dp,px等。

    3.静态static方法一般是不打算被初始化的,抽象类abstract是不能被创建出实例的/初始化(能继承)。那么非抽象类怎么能不被初始化呢?----构造函数声明成私有的privite。Math的构造函数就是私有的,所以Math不能创建出实例。

    4.静态类:一般情况下是不可以用static修饰类的。除非是内部类(类里面建的类)。

    5.静态方法不能调用非静态的变量。静态方法是独立的方法与类无关,所以不能调用类里的实例变量。

    6.静态方法也不能调用非静态方法。------可以调用静态方法。

    7.静态变量:可以变,但它的值对于所有的实例来说都是一样的,共享的。真正的全局变量。----静态变量只会有一份,也就是不能重名----例A类调用静态变量aaa赋值2,类B调用aaa时值也变2。

    8.静态变量会在该类的任何静态方法执行前就初始化。

    9.final:一个被标记为final的变量代表初始化以后就不会在改动。常数。

    10.静态的final变量是常数。public static final PI=3.14;---public:全局的 || static不用被new直接用 || final不能改的。

    11.常量名称一般都是大写的。

    12.★★★final的变量代表不能改, final的方法代表不能被覆盖,final的类代表不能被继承

    13.常量就是把变量同时标记为static和final。

    14.Math的方法Math.random()生成随机数0-1---Math.abs()绝对值---Math.round()四舍五入---min,max等

    15.primitive主数据类型的包装。如果要把主数据类型当成对象处理,得用它们的包装(大写+全称)。Boolean/Integer/Float等。如:List< Integer> a=new ArrayList();

    16.数据格式化:String.format("%,d",1000); %:代表后面的参数放这;“,”代表用,相隔;d代表十进制整数。 例:String.format("I have %.2f bug",12345.6789) > I have 12345.68 bug ==%:代表后面的参数放这-- .2f代表保留两位小数的float。------%d 十进制int;%f float;%x byte/short/int/long/BigInteger;%c=%x-BigInteger;

    17.日期:要取得当前日期用Date,其余用Calendar。因为Date很多都弃用了。

    18.Calendar a=new Calendar();这是错的Calendar是抽象类不能new 只能继承。要获得Calendar得Calendar.getInstance();调用该方法获得他的子类。

    总结:抽象-abstract:★继承树上层的全是抽象类,最下层叫具体类。抽象类不能被new创建,只能被继承。★抽象方法必须被子类覆盖实现,抽象方法没有具体方法体,只声明一个名就行,用途:BaseActivity:public abstract void initView();
    接口-interface 自带public+abstract----接口是对事物属性和行为的更高层次的抽象,对修改封闭,对扩展开发。接口自带abstract,所以接口里声明的方法必须被覆盖,而且使用;结束。void onSuccess();
    静态-static ★静态类:一般情况下是不可以用static修饰类的。除非是内部类。★静态方法:标记出不需要实例的方法。->没有对象/不能new/不能初始化 可以直接调用其方法而不用new一整个类,工具方法一般用static标记 ★静态变量:全局共享的变量,一个类修改它的值,所有的类的值都变了
    final-最终的(直译)★final的变量代表不能改,★final的方法代表不能被覆盖,★final的类代表不能被继承

  • 异常处理
    1.异常时一种Exception类型的对象。try{//危险动作}catch(Exception ex){//尝试恢复}

    2.会抛出异常的方法必须声明 throws Exception,方法可以抓住其他方法抛出的异常丢给调用方。

    3.可以用throw关键词抛出异常对象:throw new Fileaaaa();先运行try,如果没问题try跑完跑finally,如果遇到问题了,那行运行完了直接运行catch然后finally。

    try{  
        aaa();  
      }catch(BakingException ex){  
       ex.printStackTrace();  
     }finally{  
       bbb();  
     }  
    

    4.catch可以有多个,抛出多个异常,会看抛出的是什么异常具体执行那里。异常是对象,所以异常也是多态的,可以抛出一个父类异常来处理也可以一个一个抛出子类来处理,具体得看情况。有多个catch快的时候得从小排到大

    5.如果不想处理可以duck掉异常(不处理直接扔出去),但是异常肯定得处理。laundry.doLaundry();

  • 序列化和文件输入\出
    1.序列化(serialization)。如果只有自己的java程序需要这些数据,可以将被序列化的对象写到文件中。这样比纯文本文件更容易恢复而且更安全。
    2.序列化:将对象转化成01组成的字节串流。

    FileOutputStream fileOutputStream=new FileOutputStream("MyGame.ser");//FileOutputStream存取文件的对象  
    ObjectOutputStream os=new ObjectOutputStream(fileOutputStream);//连接文件和写入的对象
    os.writeObject(aaa);//将对象序列化并写入
    os.close();   
    

    3.serialization接口。标记接口。目的:声明该类是可以被序列化的。一个类如果要被序列化,则跟他有关的所有子类都要可以被序列化,都要继承serializable。

    4.序列化的对象中,如果一个实例变量不需要被序列化,则可以用transient(瞬时)标记。(transient String userId;)用途:一些变量只能在执行时要使用,但是不能被存储。

    5.解序列化(Deserialization):

    FileInputStream fileOutputStream=new FileInputStream("MyGame.ser");//FileOutputStream存取文件的对象  
    ObjectInputStream os=new ObjectInputStream(fileOutputStream);//连接文件和写入的对象
    Object o=os.readObject();//每次调用会从os中读一个对象出来,顺序=存入顺序。
    AAA aaa=(AAA)o;//将Object转化成AAA对象
    os.close();    
    

    6.直接将String写入txt。只要将FileOutputStream换成FileWrite。

    FileWrite fileWrite=new FileWrite("MyGame.txt");//创建文件,有就用,没有就建
    fileWrite.write("aaaaaa");//写入aaa
    fileWrite.close();    
    

    7.缓冲区(Buffered):提升效率可以不必一次一次写入,缓冲区里可以多存点东西,然后一次性写入。

    BufferedWriter writer=new BufferedWriter(new FileWrite("MyGame.txt"));
    writer.write("aaaaaa");//写入aaa
    writer.write("bbb");
    writer.write("ccc");
    writer.flush();//一次性写入  flush  
    

    8.读取txt文件 Flie代表文件的路径,而不是文件本身

    File file=new File("MyGame.txt");
    FileRead fileRead=new FileRead(file);//读取文件
    BufferedRead read=new BufferedRead(fileRead);//用缓冲区读
    while(read.readLine()!=null){
    String a= read.readLine();//循环读出a=aaa;a=bbb;a=ccc;   
    }
    read.close();    
    

    9.split可以分割String:String a[]=aaa.split(","); //把aaa用,分割存在一个列表

  • 网络与线程
    1.Socket是代表两台机器之间网络连接的对象(java.net.Socket)。 Socket socket=new Socket("196.164.1.102","8080");//要建立Socket连接必须知道IP地址和端口号。

    2.一个地址一共有65536个端口。0-1023是给系统的 1024-65535是可以用的。

    3.读取数据(通过BufferedRead):

    Socket socket=new Socket("196.164.1.102","8080");//建立Socket连接
    InputStreamReader stream=new  InputStreamReader(socket.getInputSteam());//建立连接到Socket上低层输入串流InputStreamReader--取得Socket上的输入串流
    BufferedRead read=new BufferedRead(stream);//用缓冲区读
    while(read.readLine()!=null){
    String a= read.readLine();//循环读出a=aaa;a=bbb;a=ccc;   
    }
    read.close();    
    

    4.写数据,可以用BufferedWriter也可以用PrintWriter(每次写入一个String)

    Socket socket=new Socket("196.164.1.102","8080");//建立Socket连接
    PrintWriter printWriter=new PrintWriter(socket.getOutputSteam());//建立连接到Socket上的PrintWriter
    printWriter.print("aaa");//写入数据
    

    5.线程Thread。多线程,java虚拟机会在主线程和其他线程之间快速来回切换直至执行完毕。外面看起来就像是同时进行的。

    6.每一个线程Thread都需要一个任务Runnable来执行。
    ①创建线程任务Runnable
    Runnable runnable=new MyRunnable();
    ②创建thread(工人)对象并赋值Runnable(给工人任务)
    Thread thread=new Thread(runnable);
    ③启动
    thread.start();
    也就是正常写法:

    Thread thread=new Thread(new Runnable() {
     @Override
      public void run() {
       
      }
      });
     thread.start();
    

    7.线程三种状态:新建(new Thread)→可执行(t.start()以后)→执行中
    正常状态:线程start以后就会在可执行与执行中来回切换
    另一种情况:堵塞状态。---sleep()或者线程调度器(scheduler)锁住了(locked)。

    8.线程调度器决定线程的状态,调度器没法用代码控制。

    9.确保各个线程都有机会执行(更好预测),最好方法就是让他们周期性的sleep();sleep方法可能会抛出InterruptedExption异常,所以得用try包起来。

    10.线程锁:synchronized(同步化)。使用synchronized关键词来修饰方法使他每次只能被单一的线程存取。锁上以后一个线程执行完事了,下一个线程才能执行。这样保证了数据不乱(并发性)也保证了A线程执行完,数据变100。B是从100开始执行变200(并行性)。

    11.锁是加在对象上的,不是方法上的。对象里有两个方法,上锁以后,两线程无法同时进入这个对象(同一个或者不同方法)。

    12.死锁。两个线程相互等待对方持有的东西。这样就卡死了。java没有处理死锁的机制,甚至不知道已经死锁了。

  • 集合与泛型
    1.集合:ArrayList、TreeSet(有序不重复)、HashMap(键值对存储)、LinkedList(经常增删用)、HashSet(不重复,查找快速)、LinkedHashMap(键值对存储,可以记住插入顺序并排序)

    1.1 List 可重复 Set 不可重复 Map 键值对,key不可重复,值可以重复

    2.泛型。泛型意味着更好的安全性。泛型的主要目的是让集合更安全。---T-E(element元素) 等。例:List《Dog》、List《Cat》等。可以用任何字符串,但是习惯用单一字母,并且除了集合用E其他一般用T。

    public static<T extends Comparble<?super T>> void sort(List<T> list)
    
    //sort方法参数是List,T类型
    -----T类型的解释是<T extends Comparble<?super T>
    ----T 是Comparble<?super T>(T必须实现Comparble)
    ---Comparble比较大小的java类。
    ---?=万用字符。<?super T>=T或者T的父类  
    
    1.public static<T extends Comparble<?super T>> void sort(List<T> list)2.public static<T extends Comparble<T>> void sort(List<T> list)
    1.表示只要是T或者T的父类就可以比较大小
    2.表示T类型可以比较大小
    
    1.public <T extends Animal> void sort(List<T> list)
    2.public void sort(List<? extends Animal> list)
    这两个是一样的