关于java的基础总结

方法区(静态区)的特点是:

  1. JVM只有一个方法区,被所有线程使用;
  2. 方法区实际上也是堆,只是用于存储类,常量相关的信息;
  3. 用来存放程序是永远不变或唯一的内容。

堆的特点如下:

  1. 堆用于存储创建好的对象和数组(数组也是对象),
  2. JVM只有一个堆,被所有线程分享;
  3. 堆是一个不连续的内存空间,分配灵活,速度慢

栈的特点如下:

  1. 栈的描述的是方法执行的内存模型,每个方法被调用都会创建一个栈帧(存储局部变量,操作数,方法出口等);
  2. JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数,局部变量);
  3. 栈属于线程私有,不能实现线程间的共享;
  4. 栈的存储特点是“后进先出,先进后出”;
  5. 栈是由系统自动分配,速度快!栈就是一个连续的存储空间。

构造器:也称构造方法,用于对象的初始化。

要点:

  1. 通过new关键字调用
  2. 构造器虽有返回值,但是不能定义返回值类型(返回值类型肯定是本类),不能再构造器里使用return返回某个值。
  3. 如果我们没有定义构造器,则编译器会自动定义一个无参构造器。如果已经定义,则编译器不会自动添加!
  4. 构造器方法名必须与类名一致。

垃圾回收机制:

  1. 发现无用对象;
  2. 回收无用对象占用的内存空间

垃圾回收相关算法:

  1. 引用计数法

堆中每个对象都有一个引用计数器,被引用一次,计数加一,被引用变量值变为null,则计数减1,直到计数为0,则变成无用对象,优点是短发算法简单,缺点是“引用无用对象”,无法识别。

  1. 引用可达法(根搜索算法)

程序把所有的引用关系看作是一张图,从一个节点GC ROOT,寻找对应应用节点,找到这个节点以后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的节点则被认为是个没有被引用的节点,即无用的节点。

开发中容易造成内存泄漏的操作:

  1. 创建无用的对象
  2. 静态集合类的使用
  3. 各种连接对象(IO流对象,数据库连接对象,网络连接对象)未关闭
  4. 监听器的使用

创建对象的步骤:

  1. 分配对象空间,并将对象成员变量初始化0或空
  2. 执行属性值的显示初始化
  3. 执行构造方法
  4. 返回对象的地址给相关的变量。

this的本质是“创建好的对象地址”!由于在构造器方法调用前,对象已经创建。因此,在构造方法中也可以是使用this代表“当前对象”。

p

ackage ci.sk.ls;

public class User{
    int id;
    String name;
    String pwd;
    public User(){

    }
    public User(int id,String neme){
        super();
        this.id=id;
        this.name=name;

    }
    public User(int id,String name,String pwd){
        this.id=id;
        this.name=name;
        this.pwd=pwd;
    }
    public static void main(String[] args) {
        User u1=new User();
        User u2=new User(101,"高三");
        User u3=new User(100,"高四","123456");
    }
}

this最常用的用法:

  1. 在程序中产生二义性之处,应使用this来指明当前对象;普通方法中,this总是指向调用该方法,构造方法中,this总是指向正要初始化的对象。
  2. 使用this关键字调用重载的构造方法,避免使用相同的初始化代码块,但只能在构造方法中用,并且必须位于构造方法的第一句。
  3. this不能用于static方法中。

static关键字:

在类中,用static声明成员变量为静态成员变量,也称为类变量。类变量的生命周期和类相同,在整个应用程序执行期间都有效。

(static修饰的成员变量和方法,从属于类。普通变量和方法从属于对象)

java的参数传值机制:

  1. 基本数据类型参数传值

传递是值的副本,副本改变不后悔影响原件

  1. 引用类型参数的传递

传递的是值的副本,但是引用类型指的就是“对象的地址”,因此,副本和原参数都指向了同一个“地址”,改变副本指向地址对象的值,也就意味着原参数指向对象的值也发生了改变。

引用数据类型:包括类引用,接口引用,数组引用

包机制:

包机制是java中管理类的重要手段。开发中,我们会遇到大量同名的类,通过包我们很容易解决类重名的问题,也可以实现对类有效管理。包对于类,相当于文件夹对于文件的作用。

继承使用的要点:

  1. 父类也叫做超类,基类,派生类
  2. java只有单继承,没有像C++那样的多继承,多继承会引起混乱,使得继承过于复杂,系统难以维护。
  3. java中类没有多继承,接口有多继承。
  4. 字类继承父类,可以得到父类的全部属性和方法(除了父类的构造方法,父类私有的属性和方法)。
  5. 如果定义一个类时,没有调用extends,则它的父类是:java.lang.Object.

instanceof运算符:

instanceof是二元运算符,左边是对象,右边是类:当对象是右面类或子类所创建对象时,返回true;否则返回false

方法的重写Override:

子类通过重写父类的方法,可以用自身的行为替换父类的行为。

方法重写的三个要点:

  1. “==”:方法名,形参列表相同
  2. “<=”:返回值类型和声明异常类型,子类小于等于父类
  3. “>=”:访问权限,子类大于父类。

Object是所有java类的根基类,也就意味着所有的java对象都拥有Object类的属性和方法。

“==”代表比较双方是否相同。如果是基本类型则表示值相等,如果是引用类型则表示地址相等即是同一个对象。

Object类中定义有:public boolean equals(Object obj)方法,提供定义“对象内容相同等”的逻辑。

Object的equals方法默认就是比较两个对象的hashcode,是同一个对象的引用时返回true否则返回false,但是,我们可以根据我们自己的要求重写equals方法

super是直接父类对象的引用。可以通过super来访问父类中被子类覆盖的方法或属性。使用super调用普通方法,语句没有位置限制,可以在子类中随便调用。

若是构造放啊的第一行代码没有显式的super(....)或者this(....);那么java默认都会调用super(),含义是调用父类的无参构造方法。这里的super()可以省略。

p

ackage ci.sk.ls;

public class TestSome {
    public static void main(String[] args) {
        new ChildClass().f();
    }
}
class FatherClass{
    public int value;
    public void f(){
        value=100;
        System.out.println("fatherclass.value="+value);
    }
}
class ChildClass extends FatherClass{
    public int value;
    public void f(){
        super.f();
        value=200;
        System.out.println("childClass.valule="+value);
        System.out.println(value);
        System.out.println(super.value);
    }
}

属性/方法查找顺序;(比如:查找变量h)

  1. 查找当前中有没有属性h;
  2. 一次上溯每个父类,查看每个父类中是否有h,直到Object
  3. 如果没找到,则出现编译错误。
  4. 上面步骤,只有找到h变量,则这个过程终止。

构造方法调用顺序:

构造方法第一句总是:super(...)来调用父类对应的构造方法。所以,流程就是:先追溯到Object,然后在一次向下执行类的初始化块和构造方法,直到当前子类为止。

注:静态初始化调用顺序,与构造方法调用顺序一样,不再重复。

静态初始化块:

  1. 构造方法用于对象的初始化!静态初始化块,再向下执行子类的静态初始化块,直到我们的类的静态初始化块为止。
  2. 构造方法执行顺序和上页执行顺序一样。

继承树追溯:

属性/方法查找顺序(比如查找变量h)

  1. 查找当前类中没有属性h
  2. 一次上溯每个父类,查看每个父类中是否有h,直到object
  3. 如果没找到,则出现编译错误
  4. 上面步骤,只要找到h变量,则这个也终止

构造方法调用顺序:

构造方法第一句总是:super(。。)来调用父类对应的构造方法。所以,流程就是:先向上追溯到object,然后在依次向下执行类的初始化和构造方法,直到子类为止。

注:静态初始化快调用顺序,与构造方法调用顺序一样,不再重复。

封装的意义:

高内聚,低耦合:高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合是仅暴露少量的方法给外部使用,尽量方便外部调用。

编程中封装的具体优点:

  1. 提高代码的安全性。
  2. 提高代码的复用性。
  3. 高内聚:封装袭击,便于修改内部代码,提高可维护性。
  4. 低耦合:简化外部调用,便于调用者使用,便于扩展和协议

修饰符

同一个类

同一个包

子类

所有类

private

*

default

*

*

protected

*

*

*

public

*

*

*

*

  1. private表示私有,只能自己类访问。
  2. default表示没有修饰符修饰,只有同一个包的类能访问
  3. protected表示可以被同一个包的类以及其他包中的所有类访问
  4. public表示可以被该项目的所有包中的所有类访问

类的属性的处理:

  1. 一般使用private处理
  2. 提供相应的get/set方法来访问相关的属性,这些方法通常都是public修饰的,一提供对属性的复制与读取操作(Boolean变量的get方法是is开头的)
  3. 一些只用于本类的辅助性的方法可以用private修饰,希望其他类调用的方法用public来修饰

pa

ckage ci.sk.ls;

public class TestSome {
    private int id;
    private String name;
    private int age;
    private boolean man;
    public void setName(){
        this.name=name;
    }
    public void setAge(){
        if (age>=1&&age<=130){
            this.age=age;
        }else{
            System.out.println("请输入正常的年龄!!!");
        }
    }

    public static void main(String[] args) {
        
    }
}

多态:指的是同一个方法调用,由于对象不同可能会有不同的行为。现实生活中,同一个方法,具体实现可能会不同。

多态的要点:

  1. 多态是方法的多态,不同属性的多态(多态与属性无关)
  2. 多态的存在要有3个必要条件:继承,方法重写,父类引用指向子类对象。
  3. 父类引用指向子类对象后,用该父类引用调用子类重写的方法,此时多态就出现了。

对象的转型:

父类引用指向子类对象,我们称这个过程为向上转型,不能调用它运行时类型方法。这时,我们就需要进行类型的强制转换。

public class Demo {
    public static void main(String[] args) {
        Object obj=new String("北京");//向上可以自动转型
        //obj.charAt(0)无法调用。编译器认为obj是object类型而不是String类型
        String str=(String)obj;//向下转型

        System.out.println(str.charAt(0));//位于0索引位置的字符
        System.out.println(obj==str);//true,他们两运行时是同一个对象
    }
}

final关键字的作用:

  1. 修饰变量:被其他修饰的变量不可改变。一旦服了初值,就不能被重新赋值。

final int MAX_SPEED=120;

2,修饰方法:该方法下不可被子类重写。但是可以被重载!

fiansl void stay(){}

3,修饰类:修饰的类不能被继承。比如:Math,String等

final class A{}

代码如下:

public class Demo {
   public final void shout(){
       System.out.println("叫了一声");
   }
}
class Dog extends Demo{
    public void shout(){//出错,不能重写final修饰的方法。
        System.out.println("往往能");
    }
}

数组:数组是相同类型的有序集合。数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成。其中,每一个数据称作一个元素,每个元素可以通过一个索引(下表)来访问它们。

数组的三个基本特点:

  1. 长度是确定的。数组一旦被创建,它的大小就是不可改变的。
  2. 其元素必须是相同类型,不允许出现混合类型
  3. 数组类型可以使任何数据类型,包括基本类型和引用类型。

数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。

数组的初始化方式总共有单重:静态初始化,动态初始化,默认初始化。

  1. 静态初始化

除了用new 关键字来产生数组以外,还可以直接在定义数组的同时就为数组元素元素分配空间并赋值

int [] a={1,2,3};//静态初始化基本类型数据

Man[] mans={new Man(1,1),new Man(2,2)};//静态初始化引用类型数组。

  1. 动态初始化数组:数据定义与数组分配空间并赋值的操作分开进行

int[]

 a1=new int [2];//动态初始化数组,先分配空间
a1[0]=1;//给数组元素赋值;
a1[1]=2;//给数组元素赋值;
  1. 数组的默认初始化

数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。

i

nt a2[]=new int[2];//默认值:0,0;
boolean[] b=new boolean[2];//默认值:false,false
String[] s=new String[2];//默认值:null,null

数组的遍历:

数组元素下标区间[0,length-1].我们可以通过下标来遍历数组中的元素,遍历时可以读取元素或修改元素的值。

p

ublic static void main(String[] args) {
  int []a=new int [4];
  //初始化数组元素的值
  for(int i=0;i<a.length;i++){
    a[i]=100*i;
  }
  //读取元素的值
  for (int i=0;i<a.length;i++){
    System.out.println(a[i]);
  }
}

增强for循环for-each,是用来读取数组或几种所有的元素,即对数组进行遍历。

public static void main(String[] args) {
  String[]ss={"aa","bb","cc"};
  for (String temp:ss){//循环遍历数组把每个元素取出来放在temp变量里面
    System.out.println(temp);
  }
}

抽象方法:使用abstract修饰的方法,没有方法体,只有生命。定义的是一种“规范”,就是告诉子类必须要给抽象方法提供具体的实现。

抽象类:包含抽象方法的类就是抽象类。通过abstract方法定义规范,然后子类必须定义具体实现。通过抽象类,

我们就可以做到严格限制子类的设计,使子类之间更加通用。

用法要点:只有抽象方法的类只能定义成抽象类

抽象类不能实例化,即不能用new实例,只能用来被自类调用,

抽象类只能用来被继承

抽象方法必须被子类实现。

public abstract class Demo {
   public  abstract int aa();
  class iu extends Demo{

    @Override
    public int aa() {
      return 0;
    }
  }
}

为什么需要接口:接口和抽象类的区别:

接口就是比“抽象类”还:“抽象”的抽象类,可以更加规范的堆子类进行约束。全面专业的实现了:规范和具体实现的分离。

抽象列还提供了某些具体实现,接口不提供任何实现,接口中所有的方法都是抽象方法。接口是完全面向规范的,规定了一批具有公共方法规范。

从接口的角度看,接口定义了可以向外部提供的服务。

从接口调用者的角度看,接口定义了实现着能提供的那些服务。

接口是两个模块之间通信的标准,通信的规范。比如能把你要设计的模块之间的接口定义好,就相当于完成了系统的设计大纲,剩下的就是添砖加瓦的具体实现了。做系统时往往采用“面向接口”的思想来设计系统。

接口和实现类不是父子关系,是实现规则的关系。比如定义一个接口Runnable,car实现它就能在地上跑,Train实现它也能在地上跑,飞机实现它也能在地上跑,Train实现它也能在地上跑,也就是说,如果他是交通工具,就一定囊在地上跑,但是一定要实现Runnable接口。

接口本质讨论:

接口就是规范,定义的一组规则,体现了现实世界中“如果你是。。。则必须能。。。”的思想。如果你是天使,则必须能飞。

接口的本质是七月,就像我们人间法律一样。制定好后大家都遵守。

面向对象的精髓,是对对象的抽象,能实现这一点就是接口。设计模式所研究的,实际上就是如何理解的去抽象。

区别:普通类:具体实现

抽象类:具体实现,规范(抽象方法)

接口:规范

抽象类和抽象方法的基本用法:


public abstract class Animal {
  abstract  public  void shout();
}
class  Dog extends Animal{
    public void shout(){
        System.out.println("旺旺");
    }
    public void seeDoor(){
        System.out.println("看门");
    }
}
 class TestAbstractClass{
    public static void main(String[] args) {
        Dog a=new Dog();
        a.shout();
        a.seeDoor();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值