java基础

基础概念

  • 主函数:不是所有类都需要主函数,如果需要独立运行就需要定义主函数,主函数由jvm调用
  • 成员变量和局部变量:
    • 成员变量:定义在类中;成员变量在整个对象中有效;存在在堆中的对象中,生命期和对象相同;
    • 局部变量:定义在函数中;局部变量在自己所属的大括号中有效;存在在中,生命期为从入栈到出栈;
  • 一个类中多个构造函数,是重载的体现
  • 类:在主类中new对象,执行顺序:静态代码块(加载类时执行,只执行一次)>main()>构造代码块>构造方法。
    • 静态代码块:只在类加载执行一次
    • 构造代码块:运行构造函数前执行,包含构造函数中的共性逻辑
    • 构造函数:在与之对应的对象初始化时调用
class TestOrder{
    //可以同时有多个静态代码块
    static {
        System.out.println("static block.");
    }

    static {
        System.out.println("static block2");
    }

//    可以同时有多个构造代码块
    {
        System.out.println("construct block2.");
    }

    TestOrder(){
        System.out.println("construct function");
    }

    {
        System.out.println("construct block.");
    }

    private void printMethod(){
        System.out.println("print");
    }

    public static void main(String[] args){
//        执行顺序:静态代码块-》main-》构造代码块-》构造函数
        System.out.println("main function");
        new TestOrder().printMethod();
        /*
        *   static block.
            static block2
            main function
            construct block2.
            construct block.
            construct function
            print
        * */
    }
}
  • Person p = new Person();初始化过程
    • 加载Person.class
    • 在栈中分配p
    • 在堆中分配一个空间
    • 在分配的空间中为属性分配空间,然后对属性默认初始化
    • 对属性显示初始化
    • 构造代码块初始化
    • 构造函数初始化
    • 将堆中的对象的首地址赋值给p
  • 对象新建的方法:new、反射、clone、序列化(ObjectInputStream、ObjectOutputStream)

序列化对象:https://www.cnblogs.com/ysocean/p/6870069.html

封装

  • 好处:将变化隔离;便于使用;提高重用性;安全性
  • this:代表所在函数所属对象。哪个对象调用这个函数,this就是哪个对象
  • 用this调用构造函数,必须定义在构造函数的第一行

static

  • 对于静态变量在内存中只有一份拷贝,在方法区中,所有实例会共享这个静态变量。
  • 对于非静态变量每创建一个实例就会在堆中分配一个,存在多个拷贝
  • 静态方法中不能使用this,不能访问实例变量。
    • 因为this和具体的实例关联,静态方法没法确定要和哪个实例关联。
    • 静态方法优先于对象存在,所以没有办法访问对象中的成员
  • 静态代码块,可以存在多个,在类加载时按先后顺序依次执行它们。只执行一次
  • static final:可以理解为全局常量,一旦赋值不能修改,直接通过类名引用
  • 静态代码块如果和主函数在同一类中,优先于主函数执行

final

  • 代表最终态,不能被改变
    • final类不能有子类,其中的方法默认是final。
      • 主要用在类不能被修改扩展时
    • final方法不能被子类重写,但可以被继承。
      • 主要是为了把方法锁定不允许子类修改;
      • 编译器在遇到final会变成内嵌提高处理效率
    • final变量表赋值一次后不能修改。
      • 主要有静态变量、实例变量和局部变量。一旦给final变量初值后,值就不能再改变了
    • final不能修饰构造函数
    • 函数参数为final时,将只能读取不能修改
    • static final:
      • 可能会有风险:如果这个常量依赖第三方库中的编译时常量,一旦这个常量变化了,但是你的jar仍然是旧值,所以更新依赖后需要及时重新编译

      常量的风险:https://blog.csdn.net/Honeyhanyu/article/details/77878120?locationNum=6&fps=1

      • public static final int a = 10就是一个编译时常量,编译后将直接替换成10,a将不存在
      • public static final int b = “hello”.length()就是一个运行时常量
  • final防止重排序
    • 构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序。Person p=new Person();
    • 初次读一个包含final域的对象的引用,与随后初次读这个final域,这两个操作之间不能重排序。Person p=obj;System.out.println(obj.finalAttr);

https://blog.csdn.net/qq1028951741/article/details/53418852 final防止重排序

继承

  • 类,对父类单继承、接口多实现
  • 父类子类中出现相同名称的成员变量时,可以使用this和super进行区分
  • 重写:子类和父类出现相同方法时(方法名和参数相同,如果只是返回值不同编译将报错),子类对象调用方法为子类上的方法。
    • 子类中的访问权限要大于等于父类。(如果小于父类,在多态的情况下将无法访问)
    • 实例方法非静态方法只能重写非静态方法(编译直接报错)
    • 静态方法不能被重写,只能被子类隐藏
  • 构造函数:子类中构造函数会先调用父类的构造函数
  • super()和this()都需要定义在第一行,所以构造函数中只能二选一
  • 有时继承会破坏封装性,这个时候可以使用final来处理,将不想被重写的方法设为final

abstract

  • 抽象方法必须定义在抽象类中,要实现了所有的抽象方法才能实例化
  • 抽象类中可以定义抽象方法,由子类来进行实现
  • 抽象类中是可以有非抽象方法的
  • abstract不可以与以下修饰符共存
    • final:修饰后子类无法实现
    • private:修饰后子类没有访问权限
    • static:static修饰的方法不用实例化直接调用,但是abstract没有实现
  • 抽象类中可以没有抽象方法,但是这样没有意义,只是让该类不能实例化

interface

  • 包含全局常量(public static final)、抽象方法(public abstract)
  • interface中可以不用写public
  • 接口与接口之间存在着继承关系,接口可以多继承接口
      interface A{}
      interface B{}
      interface C extends A,B{}
    
  • 没有多继承主要是为了避免“菱形问题”,但是现在java8中引入了接口的默认方法,有可能出现菱形问题
  • 接口主要是用于扩展功能;抽象类是为了将公共方法进行抽取出来,特有方法交给子类实现

多态

  • 父类引用或者接口的引用指向了自己子类或实现类的对象。
  • 好处:提高扩展性。子类只要重写父类的方法,父类引用指向子类实例,父类引用就可以直接调用子类重写的方法
  • 弊端:父类引用只能访问父类中有的方法,不能访问子类的特有方法
    • 如果想用子类特有方法,用instanceof判断类型后,对对象进行强转
  • 前提:有继承和重写;或者存在接口实现
  • 在虚拟机层面是通过动态绑定来实现多态

Object

  • 所有类的父类
boolean equals(Object obj)//比较两个对象的地址
String toString()//将对象变成字符串
Class getClass()//获取对象的类类型
int hashCode()//将该对象的内部地址转换成一个整数来实现
finalize() //对象在回收前调用,这是最后可以获取到对象的时候
clone()// 浅拷贝:所有变量的值和之前相同,但是引用变量依然指向以前的对象
        //深拷贝:所有变量的值和之前相同,引用变量将指向被拷贝的新对象

内部类

  • 如果A类需要直接访问B类中的成员,而B类又需要建立A类的对象;将A类定义在B类中
  • 内部类:可以直接访问外部类的属性
  • 外部类:想要访问内部类(非静态内部类),需要先实例化内部类
  • 定义在成员变量位置
    • 默认修饰符时访问内部类:Outer.Inner in = new Outer.new Inner()一般很少这样用,都是通过父类方法来获取:Set<Map.Entry<String,String>> entrySet =map.entrySet();
    • private的内部类:外部无法访问
    • static的内部类:外部可以直接访问,
    • 内部类中定义static成员,那么该内部类必须是静态的
  • 定义在局部变量位置
    • 当内部类被定义在局部位置上,只能访问局部中被final修饰的局部变量。
    • 匿名内部类:没有名字的内部类。如果一个子类后只使用一次,或者作为参数传给方法,可以使用匿名内部类
    • 定义匿名内部类:需要前提,内部类必须继承一个类或者实现接口。
        final int a=10;
        new Thread(new Runnable() {
            @Override
            //定义了一个匿名内部类
            public void run() {
                System.out.println(a);
            }
        }).start();
  • 下面两个都是通过匿名内部类建立一个Object类的子类对象
        //1
        new Object(){
            void show(){
                System.out.println("show run");                
            }
        }.show();                                    //写法和编译都没问题

        //2
        Object obj = new Object(){
            void show(){
                System.out.println("show run");
            }
        };
        obj.show();                                //写法正确,编译会报错
        //匿名内部类是Object的一个子类,这里赋给Object,造成多态,所以obj只能访问Object中定义过的方法

异常

  • java.lang.Throwable
    • Error:通常是jvm发生 (eg:OutOfMemoryError)
    • Exception:异常(eg:IOException)
      • RuntimeException:运行时异常(eg:NullPointException)
  • throw:抛出的一个具体的异常类型;throw用在函数内
  • throws:声明一个方法可能抛出的所有异常信息;throws用在函数上,可能抛出多个异常
  • 异常处理:
    • 自己捕获异常:try……catch
    • 抛出异常:throw new Exception()
  • finally:注意不要在finally中return或者抛出异常
  • 异常在继承中:
    • 父类没有异常声明抛出,子类也不能有异常抛出。如果真的需要抛异常,也只能抛RuntimeException异常
    • 可以想象在多态的情况下,父类上没有声明异常,子类却声明抛出异常。使用者将无法确定是否需要捕获

http://www.cnblogs.com/BYRans/p/Java.html

不可变对象

  • java中的Integer、String都是不可变对象,一旦修改将生成新对象

自定义不可变对象

  • 将变量改为private和final
  • 提供一个带参数的构造函数
  • 不提供setter
  • 如果其中的成员变量有引用类型:在初始化时重新new一个切断和创建者的关系;get()时重新new一个实例保证外部修改不会影响到自己。
技术选型 【后端】:Java 【框架】:springboot 【前端】:vue 【JDK版本】:JDK1.8 【服务器】:tomcat7+ 【数据库】:mysql 5.7+ 项目包含前后台完整源码。 项目都经过严格调试,确保可以运行! 具体项目介绍可查看博主文章或私聊获取 助力学习实践,提升编程技能,快来获取这份宝贵的资源吧! 在当今快速发展的信息技术领域,技术选型是决定一个项目成功与否的重要因素之一。基于以下的技术栈,我们为您带来了一份完善且经过实践验证的项目资源,让您在学习和提升编程技能的道路上事半功倍。以下是该项目的技术选型和其组件的详细介绍。 在后端技术方面,我们选择了Java作为编程语言。Java以其稳健性、跨平台性和丰富的库支持,在企业级应用中处于领导地位。项目采用了流行的Spring Boot框架,这个框架以简化Java企业级开发而闻名。Spring Boot提供了简洁的配置方式、内置的嵌入式服务器支持以及强大的生态系统,使开发者能够更高效地构建和部署应用。 前端技术方面,我们使用了Vue.js,这是一个用于构建用户界面的渐进式JavaScript框架。Vue以其易上手、灵活和性能出色而受到开发者的青睐,它的组件化开发思想也有助于提高代码的复用性和可维护性。 项目的编译和运行环境选择了JDK 1.8。尽管Java已经推出了更新的版本,但JDK 1.8依旧是一种成熟且稳定的选择,广泛应用于各类项目中,确保了兼容性和稳定性。 在服务器方面,本项目部署在Tomcat 7+之上。Tomcat是Apache软件基金会下的一个开源Servlet容器,也是应用最为广泛的Java Web服务器之一。其稳定性和可靠的性能表现为Java Web应用提供了坚实的支持。 数据库方面,我们采用了MySQL 5.7+。MySQL是一种高效、可靠且使用广泛的关系型数据库管理系统,5.7版本在性能和功能上都有显著的提升。 值得一提的是,该项目包含了前后台的完整源码,并经过严格调试,确保可以顺利运行。通过项目的学习和实践,您将能更好地掌握从后端到前端的完整开发流程,提升自己的编程技能。欢迎参考博主的详细文章或私信获取更多信息,利用这一宝贵资源来推进您的技术成长之路!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值