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一个实例保证外部修改不会影响到自己。
内容概要:本文详细介绍了施耐德M580系列PLC的存储结构、系统硬件架构、上电写入程序及CPU冗余特性。在存储结构方面,涵盖拓扑寻址、Device DDT远程寻址以及寄存器寻址三种方式,详细解释了不同类型的寻址方法及其应用场景。系统硬件架构部分,阐述了最小系统的构建要素,包括CPU、机架和模块的选择与配置,并介绍了常见的系统拓扑结构,如简单的机架间拓扑和远程子站以太网菊花链等。上电写入程序环节,说明了通过USB和以太网两种接口进行程序下载的具体步骤,特别是针对初次下载时IP地址的设置方法。最后,CPU冗余部分重点描述了热备功能的实现机制,包括IP通讯地址配置和热备拓扑结构。 适合人群:从事工业自动化领域工作的技术人员,特别是对PLC编程及系统集成有一定了解的工程师。 使用场景及目标:①帮助工程师理解施耐德M580系列PLC的寻址机制,以便更好地进行模块配置和编程;②指导工程师完成最小系统的搭建,优化系统拓扑结构的设计;③提供详细的上电写入程序指南,确保程序下载顺利进行;④解释CPU冗余的实现方式,提高系统的稳定性和可靠性。 其他说明:文中还涉及一些特殊模块的功能介绍,如定时器事件和Modbus串口通讯模块,这些内容有助于用户深入了解M580系列PLC的高级应用。此外,附录部分提供了远程子站和热备冗余系统的实物图片,便于用户直观理解相关概念。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值