javaaotimc的简单介绍
本篇文章给大家谈谈javaaotimc,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
- 1、【转】如何保护Java代码
- 2、java是编译型语言还是解释型语言
- 3、苹果App是否可以使用JAVA语言进行编写?
- 4、Java 虚拟机一样的速度甚至出现AOT编译方式吗
- 5、介绍JAVA的英语短文
- 6、java基础面试题有哪些?
【转】如何保护Java代码
以下从技术角度就常见的保护措施 和常用工具来看看如何有效保护java代码:1. 将java包装成exe 特点:将jar包装成可执行文件,便于使用,但对java程序没有任何保护。不要以为生成了exe就和普通可执行文件效果一样了。这些包装成exe的程序运行时都会将jar文件释放到临时目录,很容易获取。常用的工具有exe4j、jsmooth、NativeJ等等。jsmooth生成的exe运行时临时目录在exe所在目录中或是用户临时目录 中;exe4j生成的exe运行时临时目录在用户临时目录中;NativeJ生成的exe直接用winrar打开,然后用zip格式修复成一个jar文件,就得到了原文件。如果只是为了使用和发布方便,不需要保护java代码,使用这些工具是很好的选择。2. java混淆器特点:使用一种或多种处理方式将class文件、java源代码进行混淆处理后生成新的class,使混淆后的代码不易被反编译,而反编译后的代码难以阅 读和理解。这类混淆器工具很多,而且也很有成效。缺点:虽然混淆的代码反编译后不易读懂,但对于有经验的人或是多花些时间,还是能找到或计算出你代码中隐藏的敏感内容,而且在很多应用中不是全部代码都能混淆的,往往一些关键的库、类名、方法名、变量名等因使用要求的限制反而还不能混淆。3. 隔离java程序到服务端特点:把java程序放到服务端,让用户不能访问到class文件和相关配套文件,客户端只通过接口访问。这种方式在客户/服务模式的应用中能较好地保护java代码。缺点是:必须是客户/服务模式,这种特点限制了此种方式的使用范围;客户端因为逻辑的暴露始终是较为薄弱的环节,所以访问接口时一般都需要安全性认证。4. java加密保护特点:自定义ClassLoader,将class文件和相关文件加密,运行时由此ClassLoader解密相关文件并装载类,要起到保护作用必须自定 义本地代码执行器将自定义ClassLoader和加密解密的相关类和配套文件也保护起来。此种方式能很有效地保护java代码。缺点:可以通过替换JRE包中与类装载相关的java类或虚拟机动态库截获java字节码。 jar2exe属于这类工具。5. 提前编译技术(AOT) 特点:将java代码静态编译成本地机器码,脱离通用JRE。此种方式能够非常有效地保护java代码,且程序启动比通用JVM快一点。具有代表性的是GNU的gcj,可以做到对java代码完全提前编译,但gcj存在诸多局限性,如:对JRE 5不能完整支持、不支持JRE 6及以后的版本。由于java平台的复杂性,做到能及时支持最新java版本和JRE的完全提前编译是非常困难的,所以这类工具往往采取灵活方式,该用即时编译的地方还是 要用,成为提前编译和即时编译的混合体。缺点:由于与通用JRE的差异和java运用中的复杂性,并非java程序中的所有jar都能得到完全的保护;只能使用此种工具提供的一个运行环境,如果工具更新滞后或你需要特定版本的JRE,有可能得不到此种工具的支持。 Excelsior JET属于这类工具。6. 使用jni方式保护特点:将敏感的方法和数据通过jni方式处理。此种方式和“隔离java程序到服务端”有些类似,可以看作把需要保护的代码和数据“隔离”到动态库中,不同的是可以在单机程序中运用。缺点和上述“隔离java程序到服务端”类似。7. 不脱离JRE的综合方式保护特点:非提前编译,不脱离JRE,采用多种软保护方式,从多方面防止java程序被窃取。此种方式由于采取了多种保护措施,比如自定义执行器和装载器、加密、JNI、安全性检测、生成可执行文件等等,使保护力度大大增强,同样能够非常有效地保护java代码。缺点:由于jar文件存在方式的改变和java运用中的复杂性,并非java程序中的所有jar都能得到完全的保护;很有可能并不支持所有的JRE版本。 JXMaker属于此类工具。8. 用加密锁硬件保护特点:使用与硬件相关的专用程序将java虚拟机启动程序加壳,将虚拟机配套文件和java程序加密,启动的是加壳程序,由加壳程序建立一个与硬件相关的 受保护的运行环境,为了加强安全性可以和加密锁内植入的程序互动。此种方式与以上“不脱离JRE的综合方式保护”相似,只是使用了专用硬件设备,也能很好地保护java代码。缺点:有人认为加密锁用户使用上不太方便,且每个安装需要附带一个。从以上描述中我们可以看出:1. 各种保护方式都有其优缺点,应根据实际选用2. 要更好地保护java代码应该使用综合的保护措施3. 单机环境中要真正有效保护java代码,必须要有本地代码程序配合当然,安全都是相对的,一方面看你的保护措施和使用的工具能达到的程度,一方面看黑客的意愿和能力,不能只从技术上保护知识产权。总之,在java 代码保护方面可以采取各种可能的方式,不可拘泥于那些条条框框。
java是编译型语言还是解释型语言
概念:
编译型语言:把做好的源程序全部编译成二进制代码的可运行程序。然后,可直接运行这个程序。
解释型语言:把做好的源程序翻译一句,然后执行一句,直至结束!
区别:
编译型语言,执行速度快、效率高;依赖编译器、跨平台性差些。如C、C++、Delphi、 Pascal,Fortran。
解释型语言,执行速度慢、效率低;依赖解释器、跨平台性好。如Java、Basic.
通俗的讲,编译语言是在编译后可以直接运行,而解释语言的执行需要一个解释环境。
java很特殊,java程序也需要编译,但是没有直接编译称为机器语言,而是编译称为字节码,然后用解释方式执行字节码。
JIT:
首先采用编译形式生成某种中介代码(Java bytecode/MSIL),然后在运行时将其(通常以函数或Block为单位)最终转换成机器码,然后执行,转化的机器码可以被cache,以提高重复执行的效率
JAVA的第一道工序是javac编译,当然目标文件是BYTECODE。后续可能有三种处理方式:
1. 运行时,BYTECODE由JVM逐条解释执行,
2. 运行时,部分代码可能由JIT翻译为目标机器指令(以method为翻译单位,还会保存起来,第二次执行就不用翻译了)直接执行;
3. RTSJ。继JAVAC之后执行AOT二次编译,生成静态的目标平台代码(典型的就是IBM WEBSHPERE REAL TIME)。
苹果App是否可以使用JAVA语言进行编写?
不能
Swift和Objective-C共用一套运行时环境,Swift的类型可以桥接到Objective-C(下面我简称OC),反之亦然。两者可以互相引用混合编程。其次就是,OC之前积累的很多类库,在Swift中大部分依然可以直接使用,当然,Swift3之后,一些语法改变了很多,不过还是有迹可循的。OC出现过的绝大多数概念,比如引用计数、ARC、属性、协议、接口、初始化、扩展类、命名参数、匿名函数等,在Swift中继续有效(可能最多换个术语)。Swift大多数概念与OC一样。当然Swift也多出了一些新兴概念,这些在OC中是没有的,比如范型、元组等。
但是:现阶段Swift 到底能不能取代 Objective-C?
答案是还不行。
其实到现在为止 Swift 离完全替代 Objective-C 还是很遥远,因为 Apple 内部一直在用 Objective-C 来做一些 Framework 的开发,底层也不可能用 Swift 实现,所以现在更多的替代是体现在外部开发。
二、Swift比Objective-C有什么优势?
1、Swift容易阅读,语法和文件结构简易化。
2、Swift更易于维护,文件分离后结构更清晰。
3、Swift更加安全,它是类型安全的语言。
4、Swift代码更少,简洁的语法,可以省去大量冗余代码
5、Swift速度更快,运算性能更高。
三、Swift目前存在的缺点
1、版本不稳定,之前升级Swift3大动刀,苦了好多人,swift4目前还未知
2、使用人数比例偏低,目前还是OC的天下
3、社区的开源项目偏少,毕竟OC独大好多年,很多优秀的类库都不支持Swift,不过这种状况正在改变,现在有好多优秀的Swift的开源类库了
4、公司使用的比例不高,很多公司以稳为主,还是在使用OC开发,很少一些在进行混合开发,更少一些是纯Swift开发。
5、偶尔开发中遇到的一些问题,很难查找到相关资料,这是一个弊端。
6、纯Swift的运行时和OC有本质区别,一些OC中运行时的强大功能,在纯Swift中变无效了。
7、对于不支持Swift的一些第三方类库,如果非得使用,只能混合编程,利用桥接文件实现。
四、Swift其他功能说明
1、Swift的内存管理
Swift使用自动引用计数(ARC)来简化内存管理,与OC一致。
2、Swift的可选项类型(Optionals)介绍
Swift引入了可选项类型,用于处理变量值不存在的情况。Optionals类似于OC中指向nil的指针,但是适用于所有数据类型,而非仅仅局限于类,Optionals相比于OC中的nil指针,更加安全和简明,并且也是Swift诸多最强大功能的核心。
3、Swift中的 !和 ?
这两个符号是用来标记这个变量的值是否可选,!表示可选变量必须保证转换能够成功,否则报错,但定义的变量可以直接使用;?表示可选变量即使转换不成功也不会报错,变量值为nil,如果转换成功,要使用该变量时,后面需要加!进行修饰。
Java 虚拟机一样的速度甚至出现AOT编译方式吗
不论是物理机还是虚拟机,大部分的程序代码从开始编译到最终转化成物理机的目标代码或虚拟机能执行的指令集之前,都会按照如下图所示的各个步骤进行:
其中绿色的模块可以选择性实现。很容易看出,上图中间的那条分支是解释执行的过程(即一条字节码一条字节码地解释执行,如JavaScript),而下面的那条分支就是传统编译原理中从源代码到目标机器代码的生成过程。
如今,基于物理机、虚拟机等的语言,大多都遵循这种基于现代经典编译原理的思路,在执行前先对程序源码进行词法解析和语法解析处理,把源码转化为抽象语法树。对于一门具体语言的实现来说,词法和语法分析乃至后面的优化器和目标代码生成器都可以选择独立于执行引擎,形成一个完整意义的编译器去实现,这类代表是C/C++语言。也可以把抽象语法树或指令流之前的步骤实现一个半独立的编译器,这类代表是Java语言。又或者可以把这些步骤和执行引擎全部集中在一起实现,如大多数的JavaScript执行器。
Javac编译
在Java中提到“编译”,自然很容易想到Javac编译器将*.java文件编译成为*.class文件的过程,这里的Javac编译器称为前端编译器,其他的前端编译器还有诸如Eclipse JDT中的增量式编译器ECJ等。相对应的还有后端编译器,它在程序运行期间将字节码转变成机器码(现在的Java程序在运行时基本都是解释执行加编译执行),如HotSpot虚拟机自带的JIT(Just In Time Compiler)编译器(分Client端和Server端)。另外,有时候还有可能会碰到静态提前编译器(AOT,Ahead Of Time Compiler)直接把*.java文件编译成本地机器代码,如GCJ、Excelsior JET等,这类编译器我们应该比较少遇到。
下面简要说下Javac编译(前端编译)的过程。
词法、语法分析
词法分析是将源代码的字符流转变为标记(Token)集合。单个字符是程序编写过程中的的最小元素,而标记则是编译过程的最小元素,关键字、变量名、字面量、运算符等都可以成为标记,比如整型标志int由三个字符构成,但是它只是一个标记,不可拆分。
语法分析是根据Token序列来构造抽象语法树的过程。抽象语法树是一种用来描述程序代码语法结构的树形表示方式,语法树的每一个节点都代表着程序代码中的一个语法结构,如bao、类型、修饰符、运算符等。经过这个步骤后,编译器就基本不会再对源码文件进行操作了,后续的操作都建立在抽象语法树之上。
填充符号表
完成了语法分析和词法分析之后,下一步就是填充符号表的过程。符号表是由一组符号地址和符号信息构成的表格。符号表中所登记的信息在编译的不同阶段都要用到,在语义分析(后面的步骤)中,符号表所登记的内容将用于语义检查和产生中间代码,在目标代码生成阶段,党对符号名进行地址分配时,符号表是地址分配的依据。
语义分析
语法树能表示一个结构正确的源程序的抽象,但无法保证源程序是符合逻辑的。而语义分析的主要任务是读结构上正确的源程序进行上下文有关性质的审查。语义分析过程分为标注检查和数据及控制流分析两个步骤:
标注检查步骤检查的内容包括诸如变量使用前是否已被声明、变量和赋值之间的数据类型是否匹配等。
数据及控制流分析是对程序上下文逻辑更进一步的验证,它可以检查出诸如程序局部变量在使用前是否有赋值、方法的每条路径是否都有返回值、是否所有的受查异常都被正确处理了等问题。
字节码生成
字节码生成是Javac编译过程的最后一个阶段。字节码生成阶段不仅仅是把前面各个步骤所生成的信息转化成字节码写到磁盘中,编译器还进行了少量的代码添加和转换工作。 实例构造器init()方法和类构造器clinit()方法就是在这个阶段添加到语法树之中的(这里的实例构造器并不是指默认的构造函数,而是指我们自己重载的构造函数,如果用户代码中没有提供任何构造函数,那编译器会自动添加一个没有参数、访问权限与当前类一致的默认构造函数,这个工作在填充符号表阶段就已经完成了)。
JIT编译
Java程序最初是仅仅通过解释器解释执行的,即对字节码逐条解释执行,这种方式的执行速度相对会比较慢,尤其当某个方法或代码块运行的特别频繁时,这种方式的执行效率就显得很低。于是后来在虚拟机中引入了JIT编译器(即时编译器),当虚拟机发现某个方法或代码块运行特别频繁时,就会把这些代码认定为“Hot Spot Code”(热点代码),为了提高热点代码的执行效率,在运行时,虚拟机将会把这些代码编译成与本地平台相关的机器码,并进行各层次的优化,完成这项任务的正是JIT编译器。
现在主流的商用虚拟机(如Sun HotSpot、IBM J9)中几乎都同时包含解释器和编译器(三大商用虚拟机之一的JRockit是个例外,它内部没有解释器,因此会有启动相应时间长之类的缺点,但它主要是面向服务端的应用,这类应用一般不会重点关注启动时间)。二者各有优势:当程序需要迅速启动和执行时,解释器可以首先发挥作用,省去编译的时间,立即执行;当程序运行后,随着时间的推移,编译器逐渐会返回作用,把越来越多的代码编译成本地代码后,可以获取更高的执行效率。解释执行可以节约内存,而编译执行可以提升效率。
HotSpot虚拟机中内置了两个JIT编译器:Client Complier和Server Complier,分别用在客户端和服务端,目前主流的HotSpot虚拟机中默认是采用解释器与其中一个编译器直接配合的方式工作。
运行过程中会被即时编译器编译的“热点代码”有两类:
被多次调用的方法。
被多次调用的循环体。
两种情况,编译器都是以整个方法作为编译对象,这种编译也是虚拟机中标准的编译方式。要知道一段代码或方法是不是热点代码,是不是需要触发即时编译,需要进行Hot Spot Detection(热点探测)。目前主要的热点 判定方式有以下两种:
基于采样的热点探测:采用这种方法的虚拟机会周期性地检查各个线程的栈顶,如果发现某些方法经常出现在栈顶,那这段方法代码就是“热点代码”。这种探测方法的好处是实现简单高效,还可以很容易地获取方法调用关系,缺点是很难精确地确认一个方法的热度,容易因为受到线程阻塞或别的外界因素的影响而扰乱热点探测。
基于计数器的热点探测:采用这种方法的虚拟机会为每个方法,甚至是代码块建立计数器,统计方法的执行次数,如果执行次数超过一定的阀值,就认为它是“热点方法”。这种统计方法实现复杂一些,需要为每个方法建立并维护计数器,而且不能直接获取到方法的调用关系,但是它的统计结果相对更加精确严谨。
在HotSpot虚拟机中使用的是第二种——基于计数器的热点探测方法,因此它为每个方法准备了两个计数器:方法调用计数器和回边计数器。
方法调用计数器用来统计方法调用的次数,在默认设置下,方法调用计数器统计的并不是方法被调用的绝对次数,而是一个相对的执行频率,即一段时间内方法被调用的次数。
回边计数器用于统计一个方法中循环体代码执行的次数(准确地说,应该是回边的次数,因为并非所有的循环都是回边),在字节码中遇到控制流向后跳转的指令就称为“回边”。
在确定虚拟机运行参数的前提下,这两个计数器都有一个确定的阀值,当计数器的值超过了阀值,就会触发JIT编译。触发了JIT编译后,在默认设置下,执行引擎并不会同步等待编译请求完成,而是继续进入解释器按照解释方式执行字节码,直到提交的请求被编译器编译完成为止(编译工作在后台线程中进行)。当编译工作完成后,下一次调用该方法或代码时,就会使用已编译的版本。
由于方法计数器触发即时编译的过程与回边计数器触发即时编译的过程类似,因此这里仅给出方法调用计数器触发即时编译的流程:
介绍JAVA的英语短文
电脑方面的吗??
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities. Java applications are typically compiled to bytecode that can run on any Java virtual machine (JVM) regardless of computer architecture.
The original and reference implementation Java compilers, virtual machines, and class libraries were developed by Sun from 1995. As of May 2007, in compliance with the specifications of the Java Community Process, Sun made available most of their Java technologies as free software under the GNU General Public License. Others have also developed alternative implementations of these Sun technologies, such as the GNU Compiler for Java and GNU Classpath.
One characteristic of Java is portability, which means that computer programs written in the Java language must run similarly on any supported hardware/operating-system platform. One should be able to write a program once, compile it once, and run it anywhere.
This is achieved by compiling the Java language code, not to machine code but to Java bytecode – instructions analogous to machine code but intended to be interpreted by a virtual machine (VM) written specifically for the host hardware. End-users commonly use a Java Runtime Environment (JRE) installed on their own machine for standalone Java applications, or in a Web browser for Java applets.
Standardized libraries provide a generic way to access host specific features such as graphics, threading and networking. In some JVM versions, bytecode can be compiled to native code, either before or during program execution, resulting in faster execution.
A major benefit of using bytecode is porting. However, the overhead of interpretation means that interpreted programs almost always run more slowly than programs compiled to native executables would, and Java suffered a reputation for poor performance. This gap has been narrowed by a number of optimization techniques introduced in the more recent JVM implementations.
One such technique, known as just-in-time (JIT) compilation, translates Java bytecode into native code the first time that code is executed, then caches it. This results in a program that starts and executes faster than pure interpreted code can, at the cost of introducing occasional compilation overhead during execution. More sophisticated VMs also use dynamic recompilation, in which the VM analyzes the behavior of the running program and selectively recompiles and optimizes parts of the program. Dynamic recompilation can achieve optimizations superior to static compilation because the dynamic compiler can base optimizations on knowledge about the runtime environment and the set of loaded classes, and can identify hot spots - parts of the program, often inner loops, that take up the most execution time. JIT compilation and dynamic recompilation allow Java programs to approach the speed of native code without losing portability.
Another technique, commonly known as static compilation, or ahead-of-time (AOT) compilation, is to compile directly into native code like a more traditional compiler. Static Java compilers translate the Java source or bytecode to native object code. This achieves good performance compared to interpretation, at the expense of portability; the output of these compilers can only be run on a single architecture. AOT could give Java something close to native performance, yet it is still not portable since there are no compiler directives, and all the pointers are indirect with no way to micro manage garbage collection.
Java's performance has improved substantially since the early versions, and performance of JIT compilers relative to native compilers has in some tests been shown to be quite similar.[12][13] The performance of the compilers does not necessarily indicate the performance of the compiled code; only careful testing can reveal the true performance issues in any system.
One of the unique advantages of the concept of a runtime engine is that even the most serious errors (exceptions) in a Java program should not 'crash' the system under any circumstances, provided the JVM itself is properly implemented. Moreover, in runtime engine environments such as Java there exist tools that attach to the runtime engine and every time that an exception of interest occurs they record debugging information that existed in memory at the time the exception was thrown (stack and heap values). These Automated Exception Handling tools provide 'root-cause' information for exceptions in Java programs that run in production, testing or development environments. Such precise debugging is much more difficult to implement without the run-time support that the JVM offers.
java基础面试题有哪些?
下面是10道java基础面试题,后附答案
1.什么是 Java 虚拟机?为什么 Java 被称作是“平台无关的编程语言”?
Java 虚拟机是一个可以执行 Java 字节码的虚拟机进程。Java 源文件被编译成能被 Java 虚拟机执行的字节码文件。
Java 被设计成允许应用程序可以运行在任意的平台,而不需要程序员为每一个平台单独重写或者是重新编译。Java 虚拟机让这个变为可能,因为它知道底层硬件平台的指令长度和其他特性。
2.“static”关键字是什么意思?Java 中是否可以覆盖(override)一个 private 或者是static 的方法?
“static”关键字表明一个成员变量或者是成员方法可以在没有所属的类的实例变量的情况下被访问。
Java 中 static 方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而 static 方法是编译时静态绑定的。static 方法跟类的任何实例都不相关,所以概念上不适用。
3.JDK 和 JRE 的区别是什么?
Java 运行时环境(JRE)是将要执行 Java 程序的 Java 虚拟机。它同时也包含了执行 applet 需要的浏览器插件。Java 开发工具包 (JDK)是完整的 Java 软件开发包,包含了 JRE,编译器和其他的工具(比如:JavaDoc,Java 调试器),可以让开发者开发、编译、执行 Java 应用程序。
4.是否可以在 static 环境中访问非 static 变量?
static 变量在 Java 中是属于类的,它在所有的实例中的值是一样的。当类被 Java 虚拟机载入的时候,会对 static 变量进行初始化。如果你的代码尝试不用实例来访问非 static 的变量,编译器会报错,因为这些变量还没有被创建出来,还没有跟任何实例关联上。
5.Java 支持的数据类型有哪些?什么是自动拆装箱?
Java 语言支持的 8 中基本数据类型是:
byte
short
int
long
float
double
boolean
char
自动装箱是 Java 编译器在基本数据类型和对应的对象包装类型之间做的一个转化。比如:把 int 转化成 Integer,double 转化成 double,等等。反之就是自动拆箱。
6.Java 支持多继承么?
不支持,Java 不支持多继承。每个类都只能继承一个类,但是可以实现多个接口。
7.Java 中,什么是构造函数?什么是构造函数重载?什么是复制构造函数?
当新对象被创建的时候,构造函数会被调用。每一个类都有构造函数。在程序员没有给类提供构造函数的情况下,Java 编译器会为这个类创建一个默认的构造函数。
Java 中构造函数重载和方法重载很相似。可以为一个类创建多个构造函数。每一个构造函数必须有它自己唯一的参数列表。
Java 不支持像 C++中那样的复制构造函数,这个不同点是因为如果你不自己写构造函数的情况下,Java 不会创建默认的复制构造函数。
8.Java 中的方法覆盖(Overriding)和方法重载(Overloading)是什么意思?
Java 中的方法重载发生在同一个类里面两个或者是多个方法的方法名相同但是参数不同的情况。与此相对,方法覆盖是说子类重新定义了父类的方法。方法覆盖必须有相同的方法名,参数列表和返回类型。覆盖者可能不会限制它所覆盖的方法的访问。
9.接口和抽象类的区别是什么?
Java 提供和支持创建抽象类和接口。它们的实现有共同点,不同点在于:
接口中所有的方法隐含的都是抽象的。而抽象类则可以同时包含抽象和非抽象的方法。
类可以实现很多个接口,但是只能继承一个抽象类
类如果要实现一个接口,它必须要实现接口声明的所有方法。但是,类可以不实现抽象类声明的所有方法,当然,在这种情况下,类也必须得声明成是抽象的。
抽象类可以在不提供接口方法实现的情况下实现接口。
Java 接口中声明的变量默认都是 final 的。抽象类可以包含非 final 的变量。
Java 接口中的成员函数默认是 public 的。抽象类的成员函数可以是 private, protected 或者是 public。
接口是绝对抽象的,不可以被实例化。抽象类也不可以被实例化,但是,如果它包含 main 方法的话是可以被调用的。
10.什么是值传递和引用传递?
对象被值传递,意味着传递了对象的一个副本。因此,就算是改变了对象副本,也不会影响源对象的值。
对象被引用传递,意味着传递的并不是实际的对象,而是对象的引用。因此,外部对引用对象所做的改变会反映到所有的对象上。
最后祝你面试顺利!
关于javaaotimc和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
发布于:2022-12-28,除非注明,否则均为
原创文章,转载请注明出处。