java基础

java的工作方式;

我们要做的事,就是编写源代码文件,然后由javac编译程序把文件进行编译,得到字节码文件,然后再在java虚拟机运行此程序;

在java中程序都是类组成的 ,其中有个类中有main方法,这是java程序的入口,java程序在这里开始运行,

在java中变量的类型有两种,基本类型和引用类型;

基本类型的概念可以比喻成杯子,要事先声明杯子的大小,之后才能把值存到相应的杯子中,但是引用类型就不一样了,一般引用类型变量的内存大小是相同的,它会因不同的java虚拟机而不同,然后在引用类型变量存储的不是对象的实际值;而是堆空间的地址(我理解的是在一些new出来的对象被放在的内存的某个地方;变量只是存储了这个地址));
数组犹如杯架;

1.声明一个int数组变量,数组变量是数组对象的遥控器;

int[] nums;

2.创建大小为7的int数组;并把它赋给之前声明的int[] 的nums变量;

nums = new int[7];

数组也是对象;

java注重类型;一旦声明数组是什么类型;数组元素必须是声明的那种类型;

对象的行为;

对象实例,在一个类中有变量,有方法,当一个方法需要参数时,就需要在调用的时候传入相应类型的值,因为java是强类型的;

还有在java中传递参数时是按值传递的,也就是说是拷贝一份值过去,如果参数时基本类型,在方法中改变该参数的值,不会影响到原来变量的值,但是如果是引用类型,因为传递的是地址,所以在方法内改变变量的时候,会改变对象的值;

get和set方法;是对变量的引用;

封装:

封装的基本原则:将你的实例变量标记为私有的,并提供公有的getter与setter来控制存取动作;

数组对象的行为;

变量的初始化;初始值是0或者null;

实例变量和局部变量的区别:

1.实例变量是声明在类中,而不是方法中;

2.局部变量声明后,并没有自动的初始化。在使用前,必须手工的初始化,不然编译器会报错;

3.局部变量是声明在方法中的;

变量的比较:使用==来比较两个基本数据类型变量是否相等,或者判断两个引用是否引用同一个对象;

使用equals()来判断两个对象是否在意义上相等;

 继承和多态:

子类会继承父类的实例变量和方法;在子类中如果想在某一个方法中调用父类的方法;却不覆盖父类的方法还要增加自己的行为,可以用super.xxx();

子类会继承父类所有public类型的实例变量和方法;但不会继承父类所有private类型的变量和方法;藕,

当某个方法在子类中被覆盖过,调用这个方法会调用覆盖过的版本;

多态的运行;

原本情况下,等号两边是要相同的类型,例如:Dog myDog = new Dog();

但是在多态下,引用与对象可以是不同的类型。 Animal myDog = new Dog();

这两者的类型不相同,引用变量的类型被声明为Animal,但对象是Dog。

运用多态时,引用类型可以是实际对象类型的父类;

多态不仅体现在这个变量的定义里,参数和返回类型也可以多态!;

如果你想要防止特定的方法被覆盖,可以将该方法标识final;

子类要覆盖父类的方法必须是要参数 返回类型 权限 全部一样;

接口与抽象类;

接口是多态和java的重点;

Connection是个接口,它声明个变量,赋值的语句里返回的就是实现该接口的子类的实例。

设计抽象类型很简单:abstract class Canine extends Animal{};

有些类不希望被初始化,也就是不想被new xxx();就可以把它声明为抽象类;

抽象类除了被继承之外,没有其他用途了;

除了类之外,也可以把方法标识为abstract,代表一定要被子类覆盖才可以;如果方法是抽象的,那么那个类也一定是抽象的;还必须实现所有抽象的方法;

构造器与垃圾收集器;

这里主要讲述了变量内存的问题;局部变量会变放在栈中,调用方法的时候也会在栈中,正在执行的方法会在栈顶上,

实例变量是存储在该对象的对象堆中,如果实例变量是基本类型的话,开辟相应的内存空间来存储相应类型的值,但是如果是引用类型的变量,保存的并不是对象本身,而是对象在对象堆上的地址,而什么时候在对象堆上开辟内存空间来保存这个对象,是要看哪时候new出这个对象;

创建对象的奇迹:创建对象分三个步骤:1.声明引用类型变量。2.创建对象;3.连接对象与引用;

构造函数:

构造函数没有返回类型;如果你没有写构造函数,编译器会帮我写构造函数;构造函数不会被继承;

使用构造函数来初始化对象;

父类以及继承与构造函数之间的关系

父类的构造函数在对象的生命中所扮演的角色;

当你new一个子类时,必定要触发构造函数链;

如果在子类的构造函数中,你没有写super();(调用父类的构造函数);编译器会帮你写;但是会调用父类无参构造函数;有参的构造函数需要自己手动的写;

在构造函数中 ,你也可以写this();来执行同一个类的另一个构造函数;但是在super()不能和 this();同时调用;

对象的生命周期;

如果对象生命周期要引用变量的生命舟曲而定,就要看变量到底会存活多久;

就会两种情况:局部变量;局部变量只会存活在声明该变量的方法中;当方法被执行完毕,从堆栈中弹出去之后,就会被销毁;

实例变量的寿命与对象相同,如果对象还活着,则实例变量也会是活的;

除非有对对象的引用,否则该对象一点意义也没有。

有三种方法可以释放对象的引用;

1.引用永久性的离开它的范围;

public class StackRef{
    public void foof(){
        barf();
    }
    public void barf(){
        Duck d = new Duck();
    }
}

只要barf()这个方法执行完毕,从方法的堆栈中弹出去后,d这个局部变量就会被销毁,所以引用变量消失,从而new出来的对象,也会在对象堆中消失了。

2.引用被赋值到其他的对象上;

public class ReRef{
      Duck d = new Duck;
      public void go(){
         d = new Duck();  
      }
}

d是个实例变量,当在方法go中把它重新赋给新的对象;原来的那个对象就没有了引用变量来引用它了,所以就会被销毁了;

3.直接将引用设定为null;

public class ReRef{
      Duck d = new Duck;
      public void go(){
         d = null;  
      }
}

跟前一个例子相同的道理;

数字与静态;

静态方法:

一种不依靠实例变量也就不需要对象的行为;静态方法通过static来声明;

带有静态方法的含义;

静态的方法不能调用非静态的变量;

静态的方法有也不能调用非静态的方法;

静态方法无法看到实例变量的状态;

静态变量:

它的值对所有的实例来说都是相同的;

静态变量是在类加载时被初始化的,类会被加载是因为java虚拟机认为该类需要被加载了。所以就加载了这个类;第一次有人尝试创建这个类的实例;或者使用该类的静态方法和静态变量;

静态方法和静态变量有以下两个特点:静态变量会在该类在任何对象创建之前就进行了初始化。静态变量会在该类进行静态方法的执行完成了初始化。

包装对象:每一个基本数据类型都有个包装用的类,且这些包装类都在java.lang这个包中,所以你无须

import它们,每个包装类都很好辨别,

对象的相等:如果foo与bar两对象相等,则foo equals(bar)会返回true;且两者的hashCode()

也会返回相同的值;

引用到堆上同一个对象的两个引用是相等的,如果对两个引用调用hashCode()。就会得到相同的结果;

hashcode()默认的行为会返回每个对象特有的序号. 如果想要知道两个引用是否相等,可以使用== 来比较

变量上的字节组合,如果引用到相同的对象,字节组合也会一样。

原文地址:https://www.cnblogs.com/zht0915/p/4696433.html