Java SE基础知识

本文主要是java的一些重点和难点的讲解概括

数据的转换

  1. 转换规则:从存储范围大的类型到存储范围小的类型。
  2. 具体规则为:double→float→long→int→short(char)→byte
  3. 大类型转换成小类型需要强制转换。
    语法格式为:(转换到的类型)需要转换的值

函数参数值的引用

public class MethodDemo3 {
	//方法的执行在栈内存
	public static void main(String[] args) {
		int i=1;
		int[] arr=new int[3];
		**//实参--实际传给参数的值
		**//如果传入的是基本类型数据,就是值的拷贝
		**//m(arr[0]);
		**//如果传入的是引用数据类型,就是地址值的拷贝
		**//n(arr);
		**//如果传入的是引用数据类型但是没有改变原值就不会影响结果
		mn(arr);
	                System.out.println(arr[0]);
	}
	//形参---接受值的参数
	public static void m(int i){
		i++;
	}
	public static void n(int[] arr){
		arr[0]=3;
	}
	public static void mn(int[] arr){
		arr=new int[]{7,8,9};
    }
}

方法的传值总结
如果是基本类型数据就是值得拷贝不影响原结果
如果是引用数据类型就是地址值的拷贝,如果对原堆不做操作就不会影响原结果做了操作就会影响

二维数组
存储的元素是一维数组的数组就是二维数组

int[][] arr=new int[2][3]; 可以分成声明和赋值过程
**1.数据类型[][] arr=new 数据类型[一维数组的个数][每个一 维数组元素的个数];
int[][] arr=new int[3][];
//声明了3个一维数组 
SOP(arr[0][0]);//报错 
arr[0]=new int[2];//对的
arr[1]=new int[]{1,2,3};//对的 
arr[2]={1,2,3};//错的
**2.数据类型[][] arr=new 数据类型[一维数组的个数][];
int[][] arr={{1,2},{3,6,4},{3,8}}; //指定了值就确定了长度
**3.数据类型[][] arr={{元素值1,元素值2,…},{元素值1,元 素值2,…},{元素值1,元素值2,…},…};

java内存
—存储的有变量,对存储的不再使用内容会进行立即清除,
不会对存储的内容进行初始化,方法在栈中。
—存储的是对象,包括成员变量,会对不在使用的对象在某个时间 进行回收,
会对存储的内容进行初始化。
递归次数太多,会发生栈溢出。
面向对象初步
面向对象是一种编程范式–万物皆对象
面向过程:关注每一步的代码的具体实现细节
面向对象:先把每一步的细节整合到对象,关注的是对象
只要找到对象,就能找到面向对象的所有细节,面向对象基于面向过程。
如果场景比较复杂,就用面向对象,如果场景比较简单,就用面向过程。

类与对象的关系
1. 类是对这一类对象进行抽取:对这一类对象共有的特征,抽取为属性,共有的行为
抽取为方法。
2.类就是对象的概括,是对对象的总结,对象由类创建。
p.age 中的点就是”的”意思。对象就是类的具体实现

类与对象在内存的关系
堆:在堆内存开辟空间 new Person(),方法不在堆中,属性在
堆中有默认初始值 char \u0000
String null
方法的传值总结
1.如果是基本类型数据就是值的拷贝不影响原结果
2.如果是引用数据类型就是地址值的拷贝,引用数据类型就是地址的拷贝
3.如果对原堆不做操作就不会影响原结果,做了操作就会影响
4.对象传值主要还是基本数据类型和引用数据类型***
5.使用new关键字开辟堆内存。
6.创建对象的过程同时也创建了构造方法
7.构造方法没有返回值类型连void都没有,并且与类同名
8.如果类中没有定义构造方法JVM就会默认添加一个无参的构造方法
9.构造方法可以进行有参构造,可以对对象属性进行初始化,构造方法支持重载
10.如果类中已经定义了任何形式的构造方法,jvm默认就不添加。
11. public Person(int age){ age=age}//并没有对类的属性赋值,原因是方法有就近原则,所以是方法的参数值.要想让它具有属性位置:java中所有非静态属性和方法都可以通过对象调用,此时可以通过对象调用,但不能通过对象直接调用, 可以通过this关键字–this就表示当前类对象的引用,可以指代没有创建的对象,this是很灵活的指代,可以指代刚创建的对象,也可以指代正在使用的指代(虚拟的对象),在一个构造方法中如何调用另一个构造方法:this(name);—在一个类中构造方法去调用, 其它形式的构造方法,this语句必须在首行。 this语句只能在构造方法中使用
**this:**它代表当前对象名(在程序中易产生二义性之处,应使用this来指明当前对象;
如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名;
构造代码块
{
把重复的内容构造代码块里
} 外面无分号,里面有分号
会在构造任意方法时执行时,首先执行构造代码块里面的内容,优先于任意形式的构造方法。
在类中方法外{}—构造代码块
匿名对象: 对象可以没有名字,成为匿名对象,仍可以调用类的属性和方法,new Baby().eat();
缺点:会创建多个对象,多个内存空间
优点:匿名对象当参数传递,会比较方便 f(new Baby());

局部代码块:在方法里面的代码块,局部代码块 {int i=0;j=1; sysout(i+j)}
局部代码块可以控制变量的生命周期,可以调高内存的利用率。
成员变量与局部变量的区别:1.(在方法外类内变量和方法)成为成员变量和方法
在方法和代码块中的变量称为局部变量
2.导致使用范围的区别:成员变量整个类,局部变量在方法或者代码块
3.内存:成员变量在堆中,局部变量在栈中
4.成员变量随着对象的产生而产生,对象使用完就消失
局部变量,随着方法的调用或代码块的调用产生,执行后就消失。

面向对象的特征:封装,继承,多态–(抽象)

**封装的体现-**--1.方法;
                           2.属性私有化通过公共访问方式进行正常的取值和赋值
	    	      
 **封装的好处:**增加内部实现部分的可替换性;
                         减小类之间的耦合关系,方便模块划分;
                          容易保证类内部数据间的一致性,从而提高软件的可靠性
 **封装的原则**:类常常是public;
                         成员变量常常是private;
                         构造方法一般是public;
                         方法“getter”与“setter”是 public;
                         其它方法需要根据实际的需要而定。
  class Person {
    // 私有成员变量
    private int age;
    private String name;
    // 对外提供设置成员变量的方法
    public void setAge(int a) {
	// 由于是设置成员变量的值,这里可以加入数据的验证
	if (a < 0 || a > 130) {
	     System.out.println(a + "不符合年龄的数据范围");
	     return;
	}
	    age = a; 
     }
     // 对外提供访问成员变量的方法
     public void getAge() {
	return age;
     }
}

继承关系 :1.多个类中有相同的内容,把相同的内容抽取到一个新的类,此时
可以通过extends使得原来的类与新类之间就产生了继承的关系,只能
获取部分信息,java仅支持单继承模式,子类只有一个父类,可以有多
个子类。
2.重写(覆盖)
遵循重写的原则:1.方法签名相等
2.如果父类的返回值是基本数据类型或void,那么子类的返回值就和父类相等

             class A{
			 public int m(){
			 return 1;
			 }
			 class B extends A{
			 public int m(){
			 return  2;}
			 }

如果父类的方法的返回值是引用类型 子类的方法返回的数据类型要么和父类 一致,要么是父类的子类。

class A{}
class B extends A{}
class C{
pulic A m(){
return null;}}
class extends C{
public B m(){
return null}

所有的基本数据类型都是同一数据级别
访问权限修饰符:
本类 子类 同包类 其它类
public 可以 可以 可以 可以
protected 可以 可以 可以 不可以
默认 可以 同包子类 可以 不可以
private 可以 不可以 不可以 不可以
子类方法的权限修饰符要么和父类一致,要么和
大于父类的访问权限修饰符
父类的私有方法对子类不可见,就不会发生重写
子类拿不到父类的私有信息,构造代码块和构造方法。
非静态的方法可以被对象调用
super.sleep() super代表父类对象的引用可以调用父类的属性和方法
调用父类属性和方法时不写super
jvm就会默认添加 this代表当前类的对象
构造方法默认添加父类无参的构造方法
父类对象什么时候产生?
在子类的构造方法
无论调用什么形式的构造方法都会默认调用父类的无参构造
先执行父类的无参构造,再执行子类的无参构造,即父类的
无参构造优于子类的无参构造
通过 super()调用父类的无参构造,子类中如果没有调用super()语句的
其它形式,jvm就会在所有子类构造方法中添加一个super无参构造方法

****如果子类构造定义了任意形式的super()语句,jvm就不会添加super()无参构造方法
父类如果没有提供无参构造,子类方法中必须提供对应得super语句
super语句要求在首行,不能同时出现this和super语句
****父类对象优先于子类对象
父类的构造代码块-》父类的构造方法-》子类的构造的代码块-》子类的构造方法

super的用法1.子类的构造函数如果要引用super的话,必须把super放在函数的首位.
如果想用super继承父类构造的方法,但是没有放在第一行的话,那么在super之前的语句,肯定是为了满足 自己想要完成某些行为的语句,
但是又用了super继承父类的构造方法。那么以前所做的修改就都回到以前了,就是说又成了父类的构造方法了。
2.在Java中,有时还会遇到子类中的成员变量或方法与超类(有时也称父类)中的成员变量或方法同名。因为子类中的成员变量或方法名优先级高, 所以子类中的同名成员变量或方法就隐藏了超类的成员变量或方法,但是我们如果想要使用超类中的这个成员变量或方法,就需要用到super. 尽管可以用this调用一个构造器,但却不能调用两个。

3.this和super不能同时出现在一个构造函数里面,因为this必然会调用其它的构造函数,其它的构造函数必然也会有super语句的存在,所以在同一个构造函数里面有相同的语句,就失去了语句的意义,编译器也不会通过。

4.this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。

5.从本质上讲,this是一个指向本对象的指针, 然而super是一个Java关键字。

static变量和方法
无论创建多少个对象,静态数据都只占用一份存储区域,static关键字都只占用一份存储区域。static关键字不能应用
于局部变量,因此它只能作用于域。如果一个域是静态基本类型域,且也没有对他进行初始化,那么它就会获得基本类型的
标准初值,如果它是一个对象的引用,那么他的默认值就是null

class StaticTest {
Static int i = 47;
}

现在,尽管我们制作了两个StaticTest对象,但它们仍然只占据StaticTest.i的一个存储空间。这两个对象都共享同样的i。请考察下述代码:
StaticTest st1 = new StaticTest();
StaticTest st2 = new StaticTest();
此时,无论st1.i还是st2.i都有同样的值47,因为它们引用的是同样的内存区域。
有两个办法可引用一个static变量。正如上面展示的那样,可通过一个对象命名它,如st2.i。亦可直接用它的类名引用,而这在非静态成员里是行不通的(最好用这个办法引用static变量,因为它强调了那个变量的"静态"本质)。
StaticTest.i++;
其中,++运算符会使变量增值。此时,无论st1.i还是st2.i的值都是48。
类似的逻辑也适用于静态方法。既可象对其他任何方法那样通过一个对象引用静态方法,亦可用特殊的语法格式"类名.方法()“加以引用。静态方法的定义是类似的:
class StaticFun {
static void incr() { StaticTest.i++; }
}
从中可看出,StaticFun的方法incr()使静态数据i增值。通过对象,可用典型的方法调用incr():
StaticFun sf = new StaticFun();
sf.incr();
或者,由于incr()是一种静态方法,所以可通过它的类直接调用:
StaticFun.incr();
尽管是"静态"的,但只要应用于一个数据成员,就会明确改变数据的创建方式(一个类一个成员,以及每个对象一个非静态成员)。若应用于一个方法,就没有那么戏剧化了。对方法来说,static一项重要的用途就是帮助我们在不必创建对象的前提下调用那个方法。正如以后会看到的那样,这一点是至关重要的——特别是在定义程序运行入口方法main()的时候。
和其他任何方法一样,static方法也能创建自己类型的命名对象。所以经常把static方法作为一个"领头羊"使用,用它生成一系列自己类型的"实例”。

多态
在代码的使用过程中,可以具有灵活的展现方式。
从时期的角度分析多态:编译、运行时期
编译时期多态—在编译时期绑定代码:public static void m(int i ){}
*** .java文件-编译–.class文件,通过类加载器(classLoader)加载到方法区,此时类的信息就存在
静态常量池里面。里面有类的属性和方法(静态方法存放在静态区中*所有在静态区
的变量都有一个初始值默认值和普通变量一致)然后 new 开辟一个空间,相当于从方法区拷贝一份变量。
静态类型通过地址值从堆中在静态方法区中找到静态变量的初始值 ***
静态变量可以修饰—静态变量(属性)
class加载时的内存图
static修饰的成员变量,随着类的加载(方法区的静态常量池)而加载方法区的静态区,会赋予系统默认初始值
可以通过类名.的形式调用,也可以通过对象调用

	       **注意**:类只加载一次,在类加载的过程中,自动存入方法区
	                      如果这个属性需要多个人共享,那么需要共享静态变量。
           **构造方法中可以定义静态变量么**? 不可以,构造方法是对象级别且被调用才执行,静态变量与类同级
	                                                                    随着类的加载(方法区静态常量池)而加载到静态区,存储在静态区,当方法被调用时
	                                                                   被调用在栈中执行(所有方法和语句都是在栈中执行)。
           *静态方法中不能有静态变量,因为方法在被调用时才执行。*  
	       *静态方法中不能使用 this和super(this 和super都是对象级别)
	        main 静态修饰的内容不可以**直接**调用非静态内容
	        非静态内容可以直接调用静态内容*
		    **静态方法可以重载?可以
		     静态方法可以重写么?不可以,但允许存在**
             static :修饰代码块--静态代码块
	                    在方法外类内
	       *****类只加载一次,静态修饰的内容只加载一次,用于属性初始化以及程序启动
		       默认加载的东西。  顺序————静态 -》对象 父类静态--》子类静态--》父类初始化***(包括非静态代码块,静态成员和构造方法)-------》 子类初始化, 成员变量与构造代码块谁在前面谁先执行。**

public static void m(int i,int j){}
在运行时期的多态在运行时期绑定代码:重写向上造型–声明类是父类,实际创建的是子类 Pet p=new Cat(); 能调哪些方法,看父类有没有这个方法 。
多态的含义是为了使用统一调用
运行时期多态的前提是 继承
优点: 统一调用 解耦 (耦合度 高内聚低耦合)
案例:图形类
静态代码块:
在java中使用static关键字声明的代码块。
静态块用于初始化类,为类的属性初始化。每个静态代码块只会执行一次。
由于JVM在加载类时会执行静态代码块,所以静态代码块先于主方法执行。
如果类中包含多个静态代码块,那么将按照"先定义的代码先执行,后定义的代码后执行"。(我这没作出test)
注意:
1 静态代码块不能存在于任何方法体内。
2 静态代码块不能直接访问静态实例变量和实例方法,需要通过类的实例对象来访问。
**** 静态代码块会在类被加载时自动执行。
****静态代码块只能定义在类里面,不能定义在方法里面。
** *静态代码块里的变量都是局部变量,只在块内有效。
** *一个类中可以定义多个静态代码块,按顺序执行。
*** *静态代码块只能访问类的静态成员,而不允许访问实例成员
static构造块

java自动包装机制
我们知道容器类不能放基本类型的,放进放出都要先包装和解包,所有的这些工作都是繁琐而无聊的,它早就该有自动机制了,
终于在 1.5 里得到了实现。
这里的装箱应该理解为封装对象 ,即把基础数据类型(如 int)转换成基础类型封装类的对象(如 new Integer())
拆箱就是装箱的反过程,即把基础类型封装类的对象(如 new Integer())转换为基础数据类型(如 int)。
装箱: Integer a = new Integer() ;
a = 100 ; //1.5以前不支持为对象如此赋值
拆箱: int b = new Integer(100) ;
*构造方法同其他方法一样,也可以用private修饰,私有的构造方法无法在本类外部使用,
也就导致本类无法用new实例化,这样就可以控制对象的生成。

**
构造方法的执行的顺序
继承条件下构造方法的调用规则如下:
如果子类的构造方法中没有通过super显式调用父类的有参构造方法,也没有通过this显式调用自身的其他构造方法,则系统会默认先调用父类的无参构造方法。在这种情况下,写不写“super();”语句,效果是一样的。
如果子类的构造方法中通过super显式调用父类的有参构造方法,那将执行父类相应构造方法,而不执行父类无参构造方法。
特别注意的是,如果存在多级继承关系,在创建一个子类对象时,以上规则会多次向更高一级父类应用,一直到执行顶级父类Object类的无参构造方法为止。

**final:**修饰符 :数据 方法 类
修饰的基本数据变量不能改变
数据 ** final修饰的是引用数据类型,那么修饰的是他的地址值,地址值不能改变,元素的值可以改变,引用

	              数据类型传送的是地址值的拷贝
	              final修饰的成员变量在创建时,应该赋予初值。
	              static和final共同修饰的变量称之为静态常量,静态常量要在类加载完成之前
	              进行初始化。 
	             **方法**:此时最终方法可以重载和但不支持重写
	             **类** 不可以继承但可以继承别的类

猜你喜欢

转载自blog.csdn.net/xianrenqiu1234/article/details/86308169
今日推荐