在杨晓峰老师讲的java36讲总结的 。
Java 本身是一种面向对象的语言,最显著的特性有两个方面,一是所谓的“书写一次,到处运行”(Write once, run anywhere),能够非常容易地获得跨平台能力;另外就是垃圾收集(GC, Garbage Collection),Java 通过垃圾收集器(Garbage Collector)回收分配内存,大部分情况下,程序员不需要自己操心内存的分配和回收。
我们日常会接触到 JRE(Java Runtime Environment)或者 JDK(Java Development Kit)。JRE,也就是 Java 运行环境,包含了 JVM 和 Java 类库,以及一些模块等。而 JDK 可以看作是JRE 的一个超集,提供了更多工具,比如编译器、各种诊断工具等。
分析:
我主要是从三个方面去理解的:平台无关系,面向对象,垃圾回收
1.平台无关性(根据老师总结的)
“一次编译、到处运行”说的是Java语言跨平台的特性,Java的跨平台特性与Java虚拟机的存在密不可分,可在不同的环境中运行。比如说Windows平台和Linux平台都有相应的JDK,安装好JDK后也就有了Java语言的运行环境。其实Java语言本身与其他的编程语言没有特别大的差异,并不是说Java语言可以跨平台,而是在不同的平台都有可以让Java语言运行的环境而已,所以才有了Java一次编译,到处运行这样的效果。
程序从源代码到运行的三个阶段:编码——编译——运行——调试。Java在编译阶段则体现了跨平台的特点。编译过程大概是这样的:首先是将Java源代码转化成.CLASS文件字节码,这是第一次编译。.class文件就是可以到处运行的文件。然后Java字节码会被转化为目标机器代码,这是是由JVM来执行的,即Java的第二次编译。
“到处运行”的关键和前提就是JVM。因为在第二次编译中JVM起着关键作用。在可以运行Java虚拟机的地方都内含着一个JVM操作系统。从而使JAVA提供了各种不同平台上的虚拟机制,因此实现了“到处运行”的效果。需要强调的一点是,java并不是编译机制,而是解释机制。Java字节码的设计充分考虑了JIT(just in time)这一即时编译方式,可以将字节码直接转化成高性能的本地机器码,这同样是虚拟机的一个构成部分
编写的 Java 的源代码,首先通过Javac 编译成为字节码(bytecode),然后,在运行时,通过 Java 虚拟机(JVM)内嵌的解释器将字节码转换成为最终的机器码。但是常见的 JVM,比如我们大多数情况使用的 Oracle JDK提供的 Hotspot JVM,都提供了 JIT(Just-In-Time)编译器,也就是通常所说的动态编译器,JIT 能够在运行时将热点代码编译成机器码,这种情况下部分热点代码就属于编译执行,而不是解释执行。
注意:
1. 记得老师说过C 语言有一个特点:对于每一个不同的平台,源代码都要被编译一次。不同的平台,可执行的机器码必然是不一样的。源代码自然需要依据不同的平台分别被编译。C 语言程序经常需要调用操作系统层面的 API。不同的操作系统,API 一般不同。为了支持多平台,C 语言程序的源文件需要根据不同平台修改多次。这应该是一个非常大的痛点。也可以理解成问题并不在编译上,而是在对源文件的修改上
2. 对于一次编译,到处运行的好处,jvm 层面封装了系统API,提供不同系统一致的调用行为。减少了为适配不同操作系统,不同架构的带来的工作量。
3 . 垃圾回收,降低了开发过程中需要注意内存回收的难度。降低内存泄露出现的概率。虽然也带来了一些额外开销,但是足以弥补带来的好处。合理的分代策略,提高了内存使用率。
4. jit 与其他编译语言相比,降低了编译时间,因为大部分代码是运行时编译,避免了冷代码在编译时也参与编译的问题
2.面向对象
面向对象是一种思想。它将数据和操作数据的方法封装在对象中,从而使对象有了一些功能,也就是说面向对象是将功能等通过对象来实现,将功能封装进对象之中,让对象去实现具体的细节;这种思想将数据和操作数据的方法交给对象去管理,当我们需要某些功能的时候,只要找到能够实现该功能的对象然后让他去做就ok。这样的好处是我们不需要知道这个对象是如何实现这个功能的,我们要的是一个结果。
举例:买汽车
我们并不知道汽车是怎样生产的,但是我们最后得结果就是提一辆车回来。而车是由汽车公司生产的。这里的汽车公司 就是一个对象,它是生产汽车的。
面向对象的好处:
1.面向对象这种思想符和人们思考方式的一种思考方法
面向对象的三大特征:封装,继承,和多态
1. 封装性:所谓封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。简而言之就是,内部操作对外部而言不可见(保护性)
1)实现封装的方法:final ,private,内部类,volatile
2)如何封装:private实现封装处理
让内部操作对外部不可见(在类的外部不能直接使用对象来操作属性)
可以用private来封装属性,称为私有属性
java规范,所有私有属性想要访问设置内容,提供对应getter,setter方法
-
setter:进行属性内容的设置和更改
-
getter:取的属性内容
3)类的设计原则:
-
1.类中所有属性必须使用private
-
2.属性若要被外部访问,必须定义相应的getter和setter
4).构造方法
(a)Person (b)per1 = (c) new (d)Person;
构造方法的特点:
-
a.方法名称与类名必须相同
-
b.构造方法没有返回值类型声明(*****************)
-
c.每个类至少存在一个构造方法(没有明确定义,系统默认生成一个无参构造)
-
d.若类中定义了构造方法,则默认的无参构造不再生成
(有参构造就是给属性赋值) 先赋值在传参
构造方法重载:参数个数不同
进行类定义遵循以下顺序:
-
先定义属性--> 构造方法(构造方法按照个数排序)-->普通方法
没有栈内存指向的称为匿名空间(垃圾空间)
5).this关键字
a,this调用本类属性
this.属性名 明确表示调用类中同名属性
规范:在类的普通方法中访问本类属性,一定要加this关键字
b.this调用本类方法
-
调用普通方法 this.方法名称(参数)
-
调用构造方法 this(参数)
1.this调用本类方法必须放在首行调用 编译器语法错误
2.this调用的构造方法不允许成环 编译器语法错误
c.this表示当前对象
6).static关键字
6.1. static属性(类属性)---通过类名调用
特点:
a.访问static属性应该使用类名.属性名(类属性)--描述共享概念
b.所有非staic属性(实例属性)必须在对象实例化后使用,而static属性(类属性)不受对象实例化控制。
使用static定义方法只有一个目的:某些方法不希望受到类的控制,即可以在没有实例化对象的时候执行(广泛存在 于工具类中)
实例属性与对象强相关。而静态方法与对象无关
7)4个访问权限修饰符
访问控制符存在的原因:1.让客户端程序员无法触及他们不应该的部分 2.允许类的创建者修改类的内部工作方式,不用担心会影响客户端程序员写的代码
1)Java的四种访问修饰符:public、proteced、default、private
访问权限越小,安全性越高
2)包访问权限
定义:本包下的所有源文件可以相互调用属性与方法
JDK中常用的包,
Java.lang :系统常用的基础类(Object,String,包装类),此包在JDK1.1之后自动导入
Java.util(需要导入):Java提供的工具程序包(****),类集(ArrayList,HashMap)
J.u.c :并发程序包java .util.concurrent
3)继承访问权限 protected
起到封装的作用:private,protected, default
2. 继承性:继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
原则:is a (满足这个要求)
主要作用:继承强调代码的可重用性
子类(派生类)
父类(超类,基类)
继承的实现:class 子类 extends 父类
继承的限制:
a.子类实例化前先调用父类的构造方法,产生父类后对象才调用子类构造
b.java只允许单继承不允许多继承,但是允许多层继承
class A{}
class B extends A{}
class C extends B{}
c.在进行继承时,子类会继承父类所有的结构(包含私有属性,构造方法,普通方法)
隐示继承(必须通过其他形式调用getter setter,不能直接调用)父类中所有私有操作 private
显示继承(可以直接调用):父类中的所有非私有操作
3.方法覆写(重写)override(******)
概念:发生在有继承关系的类之中,子类定义了父类的完全相同的方法(返回值,方法名,参数列表完全一样)被覆写的方法不能拥有比父类更为严格的访问控制权限
访问控制权限:private(私有访问权限)<default(啥也不写) - 包访问权限(同一个源文件中任意访问)< public(公有访问权限)
方法覆写不能出现private,隐式继承的方法无法覆写
父类方法 private
子类方法 public 这是错的
属性覆写(了解)
判断当前方法调用的哪个类的方法:
a,当前使用的对象时通过那个类new的
b,调用的方法是否被覆写,如果被覆写,则一定调用的是覆写后的方法
面试题:解释方法重载和方法重写的区别?
a.概念上
b.范围上:重载 同一个类。重写
c.权限要求:
3. 多态性(*):所谓多态就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。(利用多态可以得到良好的设计)
在Java中,对于多态的核心表现主要有以下两点:
1. 方法的多态性:
①方法的重载:同一个方法名称可以根据参数的类型或个数不同调用不同的方法体
②方法的覆写:同一个父类的方法,可能根据实例化子类的不同也有不同的实现。
2. 对象的多态性【抽象类和接口才能体会到实际用处】(前提:方法覆写):【自动,90%】
①对象的向上转型:父类 父类对象 = 子类实例。 【强制,1%】
不管是否发生了向上转型,核心本质还是在于:你使用的是哪一个子类(new在哪里),而且调用的方法是否被子
类所覆写了
②对象的向下转型:子类 子类对象 = (子类)父类实例
作用:操作参数统一
但是并不是所有的父类对象都可以向下转型 :如果要想进行向下操作之前,一定要首先
发生向上转型,否则在转型时会出现ClassCastException
问:如果向下转型存在安全隐患,那么如何转型才靠谱呢?
最好的做法就是先进行判断,而后在进行转型,那么就可以依靠instanceof关键字实现,该关键字语法如下:
子类对象 instanceof类,返回boolean类型
多态性总结:
对象多态性的核心在于方法的覆写。
通过对象的向上转型可以实现接收参数的统一,向下转型可以实现子类扩充方法的调用(一般不操作向下
转型,有安全隐患)。
两个没有关系的类对象是不能够进行转型的,一定会产生ClassCastException。