大家好,我是哪吒。
JDK:java development kit (java开发工具)
JRE:java runtime environment (java运行时环境)
JVM:java virtuak machine (java虚拟机)
Java development kit的缩写,意思是Java开发工具,我们写文档做PPT需要office 办公软件,开发当然需要开发工具了,说到开发工具大家肯定会想到Eclipse,但是如果直接安装Eclipse你会发现它是运行不起来 是会报错的,只有安装了JDK,配置好了环境变量和path才可以运行成功。这点相信很多人都深有体会。
jdk主要包含三个部分:
第一部分是Java运行时环境,JVM
第二部分是Java的基础类库,这个类库的数量还是相当可观的
第三部分是Java的开发工具,它们都是辅助你更好地使用Java的利器
① jdk中的jre
如下图:jdk中包含的jre,在jre的bin目录里有个jvm.dll,既然JRE是运行时环境,那么运行在哪?肯定是JVM虚拟机上了。另,jre的lib目录中放的是一些JAVA类库的class文件,已经打包成jar文件。
② 第二个JRE(独立出来的运行时环境)
如下图,不管是JDK中的JRE还是JRE既然是运行时环境必须有JVM。所以JVM也是有两个的。
java virtuak machine (java虚拟机)的缩写。
大家一提到JAVA的优点就会想到:一次编译,随处运行,说白了就是跨平台性好,这点JVM功不可没。
Java的程序也就是我们编译的代码都会编译为class文件,class文件就是在jvm上运行的文件,只有JVM还不能完全支持class的执行,因为在解释class的时候JVM需要调用解释所需要的类库lib,而jre包含lib类库。
JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改的运行。
JVM也是一门很深的学问,感兴趣的同学可以深入研究,只有好处,没有坏处。
其实有时候面试官问JDK和JRE的区别的目的不是想让你解释什么名词的,而是想看看你的基础和研究Java的深浅,还有另一方面就是你是不是经常喜欢问为什么。
因为this代表的是调用这个函数的对象的引用,而静态方法是属于类的,不属于对象,静态方法成功加载后, 对象还不一定存在。 this代表对本类对象的引用,指向本类已创建的对象。 super代表对父类对象的引用,指向父类对象。 静态优先于对象存在,方法被static修饰之后,方法先存在,所需的父类引用对象晚于该方法的出 现,也就是super所指向的对象还没出现,当然就会报错。
get和post是表单提交的两种方式,get请求数据通过域名后缀URL传送,用户可见,不安全,post请求数据通过在请求报文正文里传输,相对比较安全。get是通过URL传递表单值,post通过URL看不到表单域的值。
get传递的数据量是有限的,如果要传递大数据量不能用get,不如type=“file”上传文章、type=“password”传递密码,get和post是表单提交数据的两种方式,get请求数据通过地域名后缀URL传送,用户可见,不安全,post请求数据通过将在请求报文正文里传输,相对比较安全。
get是通过url传递表单值,post通过url看不到表单域的值;
get传递的数据量是有限的,如果要传递大数据量不能用get,比如type=“file”上传文章、type=“password”传递密码或者< text area >发表大段文章,post则没有这个限制;
post会有浏览器提示重新提交表单的问题,get则没有(加分的回答)
对于Post的表单重新敲地址栏再刷新就不会提示重新提交了,因为重新敲地址就没有偷偷提交的数据了。Post方式的正确的地址很难直接发给别人。
get是从服务器获取数据,post向服务器传送数据。
get是把参数数据队列加到提交表单的action属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML.header内一起传送到action属性所指的URL地址。用户看不到这个过程。
对于get方式,服务器端用request.querystring获取变量的值,对于post方式,服务器端用request.form获取提交的数据
get传送的数据量较小,不能大于2KB.POST传送的数据量较大,一般被默认为不受限制。但理论上,限制取决于服务器的处理能力。
get安全性较低。post安全性较高。
在说堆和栈之前,先说一下JVM(虚拟机)内存的划分:
Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的。JVM运行时在内存中开辟一片内存区域,启动时在自己的内存区域中进行更细致的划分,因为虚拟机中每一片内存处理的方法都不同,所以要单独进行管理。
JVM内存的划分有五片:
我们来重点说一下堆和栈:
栈内存:栈内存首先时一片内存区域,存储的都是局部变量,凡是定义在方法中的都是局部变量,for循环内部定义的也是局部变量,是先加载函数才能进行局部变量的定义,所以方法先进栈,然后再定义变量,变量有自己的作用于,一旦离开作用域,变量就会被释放。栈内存的更新速度很快,因为局部变量的声明周期都很短。
堆内存:存储的是数组和对象(其实数组就是对象),凡是new建立的都是在堆中,堆中存放的都是实体(对象),实体用于封存数据,而且是封存多个(实体的多个属性),如果一个数据消失,这个实体也没有消失,还可以用,所以堆是不会随时释放的,但是栈不一样,栈里存放的都是单个变量,变量被释放了,也就没有了。堆里的实体虽然不会被释放,但是会被当做垃圾,Java有垃圾回收机制不定时的收取。
下面我们通过一个图例详细讲一下堆和栈:
比如主函数里的语句
int[] arr = new int[3];
在内存中是怎么被定义的:
主函数先进栈,在栈中定义一个变量arr,接下来为arr赋值,但是右边不是一个具体值,是一个实体。实体创建在堆里,在堆里首先通过new关键字开辟一个空间,内存在存储数据的时候都是通过地址来实现的,地址是一块连续的二进制,然后给这个实体分配一个内存地址。数组都有一个索引,数组这个实体在堆内存中产生之后每一个空间都会默认的初始化(这是堆内存的特点,未初始化的数据是不能用的,但是在堆里是可以用的,因为初始化过了,但是栈里没有),不同的类型初始化的值不一样,所以堆和栈里就创建了变量和实体。
那么堆和栈怎么联系起来的呢?
我们刚刚说郭给堆分配一个地址,把堆的地址赋给arr,arr就通过地址只想了数组。所以arr想操作数组时,就通过地址,而不是直接把四蹄都赋给它。这种我们不再叫它基本数据类型,而叫引用数据类型。称为arr引用了堆内存当中的实体。
如果当int[] arr = null;
arr不做任何指向,null的作用就是取消引用数据类型的指向。
当一个实体,没有引用数据类型指向的时候,它在堆内存中不会被释放,而被当作一个垃圾,在不定时的时间内自动回收,因为Java有一个自动回收机制。自动回收机制自动监测堆里是否有垃圾,如果有,就会自动的做垃圾回收的动作,但是什么时候回收不一定。
所以堆和栈的区别很明显:
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法,这种动态获取、调用对象方法的功能成为Java语言的反射机制。
反射机制是很多Java框架的基石。
① 在xml文件或properties里面写好了配置,然后再Java类里面解析xml或properties里面的内容,得到一个字符串,然后用反射机制,根据这个字符串获得某个类的Class实例,这样就可以动态配置一些东西,不用每一次都要在代码里去new或者做其它事情,以后要改的话直接改配置文件,代码维护起来就很方便了。
② 有时候要适应某些需求,Java类里面不一定能直接调用另外的方法,这时候也可以通过反射机制来实现。
反射的代码比正常调用的代码更多,性能更慢,应避免使用反射。
本文收录于,49天精通Java从入门到就业。
全网最细Java零基础手把手入门教程,系列课程包括:基础篇、集合篇、Java8新特性、多线程、代码实战,持续更新中(每周1-2篇),适合零基础和进阶提升的同学。
哪吒多年工作总结:Java学习路线总结,搬砖工逆袭Java架构师。