- 浏览: 538738 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
飞天奔月:
public List<String> gener ...
实践中的重构30_不做油漆匠 -
在世界的中心呼喚愛:
在世界的中心呼喚愛 写道public class A {
...
深入理解ReferenceQueue GC finalize Reference -
在世界的中心呼喚愛:
在世界的中心呼喚愛 写道在世界的中心呼喚愛 写道在classB ...
深入理解ReferenceQueue GC finalize Reference -
在世界的中心呼喚愛:
在世界的中心呼喚愛 写道在classB的finalize上打断 ...
深入理解ReferenceQueue GC finalize Reference -
在世界的中心呼喚愛:
iteye比较少上,如果可以的话,可以发e-mail交流:ch ...
深入理解ReferenceQueue GC finalize Reference
引言
Java的对象被jvm管理,单个对象如何布局,大小如何,程序员可以不用关心。
但是,掌握一些相关的知识,可以让我们对应用中使用的对象大小有一个大致的估计,做到心中有数,当遇到内存敏感型应用时,可以通过适当的参数调节和应用优化减少内存占用。
另外,just for fun。
声明
以下讨论大部分都是基于32bits Java Hotspot VM,关于64bits的会特殊声明。
本文查看java对象的内存输出来自工具包memoryutil
http://zhang-xzhi-xjtu.iteye.com/admin/blogs/2116347
Java对象内存组成
对象内存由以下几部分组成:Object header + primitive fields + reference fields + padding
Object header :
对象头。Hotspot中,一般对象(非数组对象)为8bytes,数组对象为12bytes。
primitive fields :
boolean byte 1
char short 2
int float 4
long double 8
reference fields :
4 bytes
padding :
为了内存对齐的填充字节。
Hotspot中,对象占据的内存是8字节的整数倍。如果不是,则加padding到8字节的整数倍。注意,padding不一定是padding到所有field之后,field有可能重新排序,以满足一定的对齐规则,padding也有可能插入到不同的地方,参见下文的例子。
shallow size和full size
我们计算new A()占据的内存时:
对象头, id(primitive)所占据的内存,str的reference内存,padding。为shallow size。
对象头, id(primitive)所占据的内存, str的reference内存,padding,str实例本身所占据的内存(full size)。为full size。
简单普通对象例子
一个new Object()占据8bytes,只有对象头。
shallow size=full size=8
class ObjectWithOneBooleanField {
boolean b;
}
一个new ObjectWithOneBooleanField()占据16bytes.
shallow size=full size=8(对象头)+1(boolean)+7(padding)=16
当一个class定义了8个boolean的field。一个对象还是占据16bytes。这种情况下无padding。
shallow size=full size=8(对象头)+8(boolean*8)=16。
class A {
boolean val0;
long val1;
int val2;
}
一个new A()占据24bytes.
shallow size=full size=8(对象头)+1(boolean)+8(long)+4(int)+3(padding)=24
数组及例子
数组是特殊的对象。对象头为12。4bytes保存length。
多维数组不过就是数组的数组。
一维primitive数组
new byte[0]
shallow size=full size=12(对象头)+4(padding)=16
new byte[4]
shallow size=full size=12(对象头)+4(byte*4)=16
new byte[5]
shallow size=full size=12(对象头)+5(byte*5)+7(padding)=24
一维reference数组
new Object[] {}
shallow size=full size=12(对象头)+4(padding)=16
new Object[] { new Object(), new Object() }
shallow size=12(对象头)+8(reference*2)+4(padding)=24
full size=24(shallow size)+16(2个空object的内存,每个8bytes)=40
二维数组
new Object[][] {
new Object[] { new Object() },
new Object[] { new Object(), new Object() }
}
shallow size=12(对象头)+8(reference*2)+4(padding)=24
对new Object[] { new Object() }
shallow size=12(对象头)+4(reference)=16
full size=16(shallow size)+8(空对象大小)=24
对new Object[] { new Object(), new Object() }
Full size=40(前文计算过)
合起来 full size=24+24+40=88
Field重排序
我们来看一个例子。
ClassWithManyFields
----------------------------------------------------------------
object class info : allen.memoryutil.dirver.ClassWithManyFields
object identityHashCode : 10851992
in parent info : root object
shallow size = 40
full size = 40
-----------shallow size detail.-----------------
headerType = NormalHeader size = 8
offset : 8 size = 8 long allen.memoryutil.dirver.ClassWithManyFields.val1
offset : 16 size = 8 long allen.memoryutil.dirver.ClassWithManyFields.val3
offset : 24 size = 8 long allen.memoryutil.dirver.ClassWithManyFields.val5
offset : 32 size = 4 int allen.memoryutil.dirver.ClassWithManyFields.val2
offset : 36 size = 1 boolean allen.memoryutil.dirver.ClassWithManyFields.val0
offset : 37 size = 1 boolean allen.memoryutil.dirver.ClassWithManyFields.val4
padding size = 2
-----------end of shallow size detail.----------
----------------------------------------------------------------
可以看出,field被重新排序,以保证K长度的数据类型地址都是K的整数倍。
类继承关系对内存布局的影响
Child
----------------------------------------------------------------
object class info : allen.memoryutil.dirver.Child
object identityHashCode : 15244180
in parent info : root object
shallow size = 32
full size = 32
-----------shallow size detail.-----------------
headerType = NormalHeader size = 8
offset : 8 size = 8 long allen.memoryutil.dirver.Father.father_long
offset : 16 size = 1 byte allen.memoryutil.dirver.Father.father_byte_0
offset : 17 size = 1 byte allen.memoryutil.dirver.Father.father_byte_1
offset : 20 size = 1 byte allen.memoryutil.dirver.Child.child_byte_0
offset : 21 size = 1 byte allen.memoryutil.dirver.Child.child_byte_1
offset : 24 size = 8 long allen.memoryutil.dirver.Child.child_long
padding size = 4
-----------end of shallow size detail.----------
----------------------------------------------------------------
可以看到,父类的field先单独排列(有重排序),然后才是子类的field排列(有重排序)。
如何合法浪费内存
理解了内存对齐和父类的field单独排列,我们可以合法的构造浪费内存的对象。
C_D
----------------------------------------------------------------
object class info : allen.memoryutil.dirver.C_D
object identityHashCode : 30377347
in parent info : root object
shallow size = 40
full size = 40
-----------shallow size detail.-----------------
headerType = NormalHeader size = 8
offset : 8 size = 1 byte allen.memoryutil.dirver.C_A.a_byte
offset : 16 size = 8 long allen.memoryutil.dirver.C_B.b_long
offset : 24 size = 1 byte allen.memoryutil.dirver.C_C.c_byte
offset : 32 size = 8 long allen.memoryutil.dirver.C_D.d_long
padding size = 14
-----------end of shallow size detail.----------
----------------------------------------------------------------
可以看到,由于类型在继承体系中,field是byte和long间隔定义,导致padding比较大。
当类的继承链比较长时,则最多可以浪费7/16=43%的内存。
32位jvm和64位jvm
64bits JVM和32bits相比变化如下:
对象占用的内存大小受到VM参数UseCompressedOops的影响。
开启(-XX:+UseCompressedOops) 可以压缩指针。
关闭(-XX:-UseCompressedOops) 可以关闭压缩指针。
原理:
4bytes引用(地址编码),当寻址单位为1 byte时,寻址空间为4G空间。
由于java对象都是8bytes对齐的,因此,所有java对象地址的低3bits都是0,有点浪费。
如果寻址单位从1byte改为8bytes,则可以去除该浪费。
4bytes引用(地址编码),当寻址单位为8 byte时,寻址空间为32G空间。
可以看到,压缩指针技术只适用于java堆大小<=32G的情况。
UseCompressedOops默认开启规则:
Compressed oops is supported and enabled by default in Java SE 6u23 and later. In Java SE 7, use of compressed oops is the default for 64-bit JVM processes when -Xmx isn't specified and for values of -Xmx less than 32 gigabytes. For JDK 6 before the 6u23 release, use the -XX:+UseCompressedOops flag with the java command to enable the feature.
memoryutil详情输出简要说明
"abcd"字符串的详情例子
参考
http://www.javamex.com/tutorials/memory/index.shtml
http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html#compressedOop
Java的对象被jvm管理,单个对象如何布局,大小如何,程序员可以不用关心。
但是,掌握一些相关的知识,可以让我们对应用中使用的对象大小有一个大致的估计,做到心中有数,当遇到内存敏感型应用时,可以通过适当的参数调节和应用优化减少内存占用。
另外,just for fun。
声明
以下讨论大部分都是基于32bits Java Hotspot VM,关于64bits的会特殊声明。
本文查看java对象的内存输出来自工具包memoryutil
http://zhang-xzhi-xjtu.iteye.com/admin/blogs/2116347
Java对象内存组成
对象内存由以下几部分组成:Object header + primitive fields + reference fields + padding
Object header :
对象头。Hotspot中,一般对象(非数组对象)为8bytes,数组对象为12bytes。
primitive fields :
boolean byte 1
char short 2
int float 4
long double 8
reference fields :
4 bytes
padding :
为了内存对齐的填充字节。
Hotspot中,对象占据的内存是8字节的整数倍。如果不是,则加padding到8字节的整数倍。注意,padding不一定是padding到所有field之后,field有可能重新排序,以满足一定的对齐规则,padding也有可能插入到不同的地方,参见下文的例子。
shallow size和full size
class A{ int id; String str; }
我们计算new A()占据的内存时:
对象头, id(primitive)所占据的内存,str的reference内存,padding。为shallow size。
对象头, id(primitive)所占据的内存, str的reference内存,padding,str实例本身所占据的内存(full size)。为full size。
简单普通对象例子
一个new Object()占据8bytes,只有对象头。
shallow size=full size=8
class ObjectWithOneBooleanField {
boolean b;
}
一个new ObjectWithOneBooleanField()占据16bytes.
shallow size=full size=8(对象头)+1(boolean)+7(padding)=16
当一个class定义了8个boolean的field。一个对象还是占据16bytes。这种情况下无padding。
shallow size=full size=8(对象头)+8(boolean*8)=16。
class A {
boolean val0;
long val1;
int val2;
}
一个new A()占据24bytes.
shallow size=full size=8(对象头)+1(boolean)+8(long)+4(int)+3(padding)=24
数组及例子
数组是特殊的对象。对象头为12。4bytes保存length。
多维数组不过就是数组的数组。
一维primitive数组
new byte[0]
shallow size=full size=12(对象头)+4(padding)=16
new byte[4]
shallow size=full size=12(对象头)+4(byte*4)=16
new byte[5]
shallow size=full size=12(对象头)+5(byte*5)+7(padding)=24
一维reference数组
new Object[] {}
shallow size=full size=12(对象头)+4(padding)=16
new Object[] { new Object(), new Object() }
shallow size=12(对象头)+8(reference*2)+4(padding)=24
full size=24(shallow size)+16(2个空object的内存,每个8bytes)=40
二维数组
new Object[][] {
new Object[] { new Object() },
new Object[] { new Object(), new Object() }
}
shallow size=12(对象头)+8(reference*2)+4(padding)=24
对new Object[] { new Object() }
shallow size=12(对象头)+4(reference)=16
full size=16(shallow size)+8(空对象大小)=24
对new Object[] { new Object(), new Object() }
Full size=40(前文计算过)
合起来 full size=24+24+40=88
Field重排序
我们来看一个例子。
class ClassWithManyFields { boolean val0; long val1; int val2; long val3; boolean val4; long val5; }
ClassWithManyFields
----------------------------------------------------------------
object class info : allen.memoryutil.dirver.ClassWithManyFields
object identityHashCode : 10851992
in parent info : root object
shallow size = 40
full size = 40
-----------shallow size detail.-----------------
headerType = NormalHeader size = 8
offset : 8 size = 8 long allen.memoryutil.dirver.ClassWithManyFields.val1
offset : 16 size = 8 long allen.memoryutil.dirver.ClassWithManyFields.val3
offset : 24 size = 8 long allen.memoryutil.dirver.ClassWithManyFields.val5
offset : 32 size = 4 int allen.memoryutil.dirver.ClassWithManyFields.val2
offset : 36 size = 1 boolean allen.memoryutil.dirver.ClassWithManyFields.val0
offset : 37 size = 1 boolean allen.memoryutil.dirver.ClassWithManyFields.val4
padding size = 2
-----------end of shallow size detail.----------
----------------------------------------------------------------
可以看出,field被重新排序,以保证K长度的数据类型地址都是K的整数倍。
类继承关系对内存布局的影响
class Father { byte father_byte_0; long father_long; byte father_byte_1; } class Child extends Father { byte child_byte_0; long child_long; byte child_byte_1; }
Child
----------------------------------------------------------------
object class info : allen.memoryutil.dirver.Child
object identityHashCode : 15244180
in parent info : root object
shallow size = 32
full size = 32
-----------shallow size detail.-----------------
headerType = NormalHeader size = 8
offset : 8 size = 8 long allen.memoryutil.dirver.Father.father_long
offset : 16 size = 1 byte allen.memoryutil.dirver.Father.father_byte_0
offset : 17 size = 1 byte allen.memoryutil.dirver.Father.father_byte_1
offset : 20 size = 1 byte allen.memoryutil.dirver.Child.child_byte_0
offset : 21 size = 1 byte allen.memoryutil.dirver.Child.child_byte_1
offset : 24 size = 8 long allen.memoryutil.dirver.Child.child_long
padding size = 4
-----------end of shallow size detail.----------
----------------------------------------------------------------
可以看到,父类的field先单独排列(有重排序),然后才是子类的field排列(有重排序)。
如何合法浪费内存
理解了内存对齐和父类的field单独排列,我们可以合法的构造浪费内存的对象。
class C_A { byte a_byte; } class C_B extends C_A { long b_long; } class C_C extends C_B { byte c_byte; } class C_D extends C_C { long d_long; }
C_D
----------------------------------------------------------------
object class info : allen.memoryutil.dirver.C_D
object identityHashCode : 30377347
in parent info : root object
shallow size = 40
full size = 40
-----------shallow size detail.-----------------
headerType = NormalHeader size = 8
offset : 8 size = 1 byte allen.memoryutil.dirver.C_A.a_byte
offset : 16 size = 8 long allen.memoryutil.dirver.C_B.b_long
offset : 24 size = 1 byte allen.memoryutil.dirver.C_C.c_byte
offset : 32 size = 8 long allen.memoryutil.dirver.C_D.d_long
padding size = 14
-----------end of shallow size detail.----------
----------------------------------------------------------------
可以看到,由于类型在继承体系中,field是byte和long间隔定义,导致padding比较大。
当类的继承链比较长时,则最多可以浪费7/16=43%的内存。
32位jvm和64位jvm
64bits JVM和32bits相比变化如下:
对象占用的内存大小受到VM参数UseCompressedOops的影响。
开启(-XX:+UseCompressedOops) 可以压缩指针。
关闭(-XX:-UseCompressedOops) 可以关闭压缩指针。
原理:
4bytes引用(地址编码),当寻址单位为1 byte时,寻址空间为4G空间。
由于java对象都是8bytes对齐的,因此,所有java对象地址的低3bits都是0,有点浪费。
如果寻址单位从1byte改为8bytes,则可以去除该浪费。
4bytes引用(地址编码),当寻址单位为8 byte时,寻址空间为32G空间。
可以看到,压缩指针技术只适用于java堆大小<=32G的情况。
UseCompressedOops默认开启规则:
Compressed oops is supported and enabled by default in Java SE 6u23 and later. In Java SE 7, use of compressed oops is the default for 64-bit JVM processes when -Xmx isn't specified and for values of -Xmx less than 32 gigabytes. For JDK 6 before the 6u23 release, use the -XX:+UseCompressedOops flag with the java command to enable the feature.
memoryutil详情输出简要说明
"abcd"字符串的详情例子
---------------------------------------------------------------- object class info : java.lang.String //对象类型 object identityHashCode : 4875744 //对象identityHashCode in parent info : root object shallow size = 24 //对象shallow size full size = 48 //对象full size full padding size = 4 //对象full padding size -----------shallow size detail.----------------- //对象shallow size的详情信息 headerType = NormalHeader size = 8 //普通对象头,大小为8 offset : 8 size = 4 private final char[] java.lang.String.value //value field的offset为8,大小为4。 offset : 12 size = 4 private final int java.lang.String.offset //offset field的offset为12,大小为4。 offset : 16 size = 4 private final int java.lang.String.count //count field的offset为16,大小为4。 offset : 20 size = 4 private int java.lang.String.hash //hash field的offset为20,大小为4。 padding size = 0 //padding为0。 -----------end of shallow size detail.---------- //该字符串引用的char[]详情信息 object class info : char[] object identityHashCode : 15672056 in parent info : private final char[] java.lang.String.value in parent. //对象在被引用对象中的位置信息。 shallow size = 24 full size = 24 full padding size = 4 -----------shallow size detail.----------------- headerType = ArrayHeader size = 12 //数组对象头,大小为12 compType = char arrayLength = 4 size = ( 2 * 4 ) = 8 //数组的类型为char,长度为4,大小为8。 padding size = 4 //padding为4。 -----------end of shallow size detail.---------- ----------------------------------------------------------------
参考
http://www.javamex.com/tutorials/memory/index.shtml
http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html#compressedOop
发表评论
-
simplehbase v0.98.1开始支持hbase0.98
2014-12-29 21:52 782https://github.com/zhang-xzhi/s ... -
hbase轻量级中间件simplehbase v1.0简介
2014-12-13 18:56 952https://github.com/zhang-xzhi/s ... -
hbase的CoprocessorProtocol及一个简单的通用扩展实现V2
2014-12-04 18:02 867hbase中的CoprocessorProtocol机制. ... -
hbase 0.94.0 0.94.9 0.94.24 功能不兼容初步分析
2014-12-04 16:14 613hbase 0.94.0 0.94.9 0.94.24 功能不 ... -
可以查看java对象的MemoryUtil简介
2014-09-14 21:01 1263MemoryUtil 关于java对象内存的基本知识,请参考 ... -
gcviewer v0.3 一个解析CMS GC日志的GUI程序
2014-09-07 23:00 1091GCviewer https://github.com/z ... -
simplehbase版本变更
2014-07-14 13:42 740https://github.com/zhang-xzhi/s ... -
hbase ORM simplehbase/simplehbaseviewer v0.8简介及使用说明
2014-05-07 00:50 1035https://github.com/zhang-xzhi/s ... -
HBase Client使用注意点
2014-04-21 12:52 1957HBase Client使用注意点: 1 HTable线程 ... -
文件编码自动检测及编码转换encodechecker v0.5
2014-04-15 00:35 1827由于很多软件都不能准确自动识别文件编码,因此写了个文件编码识别 ... -
[perf] java常用基本操作性能测试-异常
2014-03-08 09:53 1161性能测试: 由于软硬件及其复杂,本结果只具有参考意义。 代码: ... -
[perf] java常用基本操作性能测试-反射
2014-03-07 13:06 1078性能测试: 由于软硬件及其复杂,本结果只具有参考意义。 代码: ... -
hbase轻量级中间件simplehbase v0.2简介
2013-12-22 17:58 1510https://github.com/zhang-xzhi/s ... -
mysql的一些性能数据
2012-12-01 16:04 975这个并不是一个严谨的性能测试,而是就简单的一些场景记录一些数据 ... -
有关于时间
2012-12-01 15:55 948int型如果表示ms的话,那也就是24天而已。 double ... -
我对移位操作的误解
2012-11-30 20:52 959一直以为java的移位操作只能操作int,原来是自己的误解。l ... -
Java Concurrency in Practice读书笔记
2011-08-13 10:03 2928目录 Chapter 1. Introduction 2 1. ... -
bug fix 记录
2011-01-07 21:58 1209p1 Caused by: org.xml.sax.SAXP ... -
实践中的重构10_平铺直叙的代码(new)
2011-01-06 00:09 720很多应用程序的主要目的就是用计算机来代替人处理真实世界 ... -
实践中的重构01-05
2010-11-13 01:06 1179目录 实践中的重构01_ ...
相关推荐
首先,让我们探讨Java的基础知识。Java的基础部分主要包括以下几个方面: 1. **语法基础**:Java的语法结构与C++类似,但更加严谨。包括变量定义、数据类型(如整型、浮点型、字符型和布尔型)、常量、运算符(如...
5. **面向对象编程**:虽然这不是必需的,但为了提高代码的可读性和可复用性,可以将爱心树的绘制逻辑封装在一个类中,甚至可以定义一个表示爱心的类,包含其大小、颜色等属性。 6. **异常处理**:在实际运行时,...
掌握这些基础知识可以帮助开发者更好地理解Java程序的内存消耗,从而在设计和优化时做出更明智的决策。例如,通过合理地组织数据结构和减少不必要的对象引用,可以显著降低内存使用量,进而提高应用程序的性能。同时...
Java 3D库是建立在Java 2D基础之上,扩展了2D图形的能力,提供了对3D几何、光照、纹理、动画等的支持。 在描述中提到的几个关键知识点包括: 1. **绘制文字的Image对象**:在Java中,Image对象用于表示图像数据。...
总的来说,理解Java对象在内存中的表示方式和占用空间,结合合适的工具进行监控,是开发高效、稳定的Java应用的基础。通过深入学习这些知识点,开发者可以更好地优化程序,提高系统资源利用率,避免因内存问题导致的...
1. **Java基础知识**:首先,需要了解Java的基础语法,如变量声明、数据类型、运算符、流程控制语句(if-else、while、for等)以及类和对象的概念。 2. **Scanner类**:用于从用户那里获取输入。在游戏中,玩家的...
基本数据类型的大小、取值范围和二进制位数是Java程序设计中必须要了解的基础知识。 除了上述基础知识点,Java集合框架是处理数据结构的重要组成部分,它提供了通用的数据结构如List、Set、Map等,还提供了遍历集合...
1. **基础语法**:Java是一种静态类型的面向对象语言,它的语法严谨,包括类、对象、接口、继承、封装、多态等核心概念。在计算特征时,首先需要理解如何定义和使用类以及方法来组织代码。 2. **数组和集合**:在...
3. **绘图基础**: 在Java中,`Graphics`对象是用于绘图的主要接口,它提供了诸如`drawLine()`, `fillRect()`, `drawOval()`等方法。我们可以通过实例化`Graphics2D`来获得更强的绘图能力,如抗锯齿、平滑渐变等。 4...
我们将深入探讨如何在Java中实现HTTP请求以及文件下载的相关知识点。 1. **HTTP协议基础**: - HTTP是应用层协议,基于TCP/IP通信协议,用于在Web上传输数据。 - 它分为两个主要部分:请求和响应。客户端(如...
通过`File`对象,我们可以创建、读取、写入、删除文件和目录,以及获取文件的基本属性如大小、最后修改时间等。 2. **File.copy()方法**: 尽管Java的标准库没有直接提供`File.copy()`方法,但我们可以利用`java....
Graphics对象是Java用于图形绘制的基础,它提供了各种绘制直线、曲线、形状和文本的方法。 3. **事件监听器**: 为了响应用户的鼠标点击和移动,程序需要添加事件监听器。例如,MouseListener和MouseMotionListener...
Java虚拟机(JVM)是Java程序运行的基础,它负责解释和执行字节码,提供了一个平台无关的运行环境。JVM性能优化是提升Java应用效率的关键环节,涉及到内存管理、垃圾回收、线程调度等多个方面。以下是对"Java JVM及...
通过分析这个DEMO,我们可以学习到Java中的类定义、对象创建、成员变量、构造函数、方法以及集合操作等基础知识。同时,它也为我们提供了实践OOP设计原则的机会,如封装、继承和多态。这有助于提升我们的编程思维和...
理解和掌握Java虚拟机规范对于开发高效、稳定的Java应用至关重要,它涵盖了语言特性的底层实现,也是解决性能问题和调试故障的基础。通过深入学习JVM,开发者能够更好地优化代码,提升程序运行效率。
Java 面向对象程序设计基础知识总结 Java 是一种面向对象的编程语言,下面是 Java 面向对象程序设计基础知识的总结: 1. 主类和主要方法 在 Java 中,含有 main() 方法的类称为主类,一个 .java 文件中可以有多个...
1. **Java Swing基础知识**: - Swing是Java Foundation Classes (JFC)的一部分,提供了一套用于创建桌面应用的组件。 - JFrame是主窗口类,用于承载其他组件,如JPanel、JButton、JScrollPane等。 - JTable用于...
总之,这个压缩包提供的练习题旨在帮助学习者巩固Java基础知识,掌握面向对象编程,同时深入理解JavaFX的特性和应用,为他们将来开发富客户端应用打下坚实的基础。通过实践这些代码,开发者能够提升自己的JavaFX技能...
在标签"java"中,我们可以涵盖更多关于Java语言的基础知识,例如: - 类与对象:Java是一种面向对象的语言,一切皆为对象,类是对象的模板。 - 访问修饰符:public, private, protected, default,控制类、方法和...