欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

測(cè)量Java對(duì)象所占內(nèi)存大小方式

 更新時(shí)間:2023年09月20日 14:38:35   作者:tiandee  
這篇文章主要介紹了測(cè)量Java對(duì)象所占內(nèi)存大小方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

背景:

相信大部分人都不會(huì)關(guān)注這個(gè)問題吧,只有一些偏執(zhí)狂才會(huì)抓著這些不放,我們平時(shí)寫代碼時(shí)經(jīng)常會(huì)new ArrayList<>(),new String()之類的,那么這些剛new出來的對(duì)象在內(nèi)存中占用多大空間呢?

方法一

設(shè)置-Xms和-Xmx的大小,然后在程序中循環(huán)new對(duì)象,直到發(fā)生OOM異常,記錄下此時(shí)new了多少個(gè)對(duì)象,大家覺得這種方法可靠不?

下面放上設(shè)置參數(shù)以及測(cè)試代碼。

/**
 * 研究new出的對(duì)象大小
 * -Xms1m -Xmx1m -XX:+PrintGCDetails
 */
public class TestObjectSize {
    int i = 0;
    @Test
    public void testObjectSize() {
        List<Object> list = new ArrayList<>();
        try {
            while (true) {
                list.add(new Object());
                i++;
            }
        } catch (Exception e) {
            System.out.println(i);
            e.printStackTrace();
        }finally {
            System.out.println(i);
        }
    }
}
運(yùn)行結(jié)果:
14053
java.lang.OutOfMemoryError: Java heap space

根據(jù)上面的結(jié)果可以算出每個(gè)Object對(duì)象大小1024*1024/14053=74.61Byte,這個(gè)結(jié)果好像挺意外,個(gè)人覺得有點(diǎn)大了,下面來分析一下,由于設(shè)置了-XX:+PrintGCDetails參數(shù),控制臺(tái)實(shí)時(shí)輸出GC情況,

如下圖:

可以發(fā)現(xiàn),在new對(duì)象的過程中執(zhí)行了六次GC(Minor GC),也就是說JVM在青年代區(qū)回收了6次垃圾,執(zhí)行了N次FullGC,F(xiàn)ullGC會(huì)回收PSYoungGen、ParOldGen、Metaspace,這么看來這個(gè)結(jié)果是不可可信的,因?yàn)榛厥盏倪^程中,銷毀了很多對(duì)象,但是計(jì)數(shù)器一直是增加的,所以74.61Byte這個(gè)結(jié)果毫無疑問是偏大的。

【錯(cuò)誤糾正】

經(jīng)過同事的糾正,回收過程中Object對(duì)象不會(huì)被銷毀,因?yàn)楸环诺搅薼ist中,list并不會(huì)銷毀,因此在執(zhí)行GC過程中,只是在不斷地搬家,從一個(gè)survivor到另一個(gè)survivor.

方法二

利用java.lang.instrument.Instrumentation這個(gè)interface的特有屬性,可以在JVM運(yùn)行過程中實(shí)時(shí)測(cè)量對(duì)象大小。簡(jiǎn)單介紹下這個(gè)類,利用 Java 代碼,即 java.lang.instrument 做動(dòng)態(tài) Instrumentation 是 Java SE 5 的新特性,它把 Java 的 instrument 功能從本地代碼中解放出來,使之可以用 Java 代碼的方式解決問題。使用 Instrumentation,開發(fā)者可以構(gòu)建一個(gè)獨(dú)立于應(yīng)用程序的代理程序(Agent),用來監(jiān)測(cè)和協(xié)助運(yùn)行在 JVM 上的程序,甚至能夠替換和修改某些類的定義。有了這樣的功能,開發(fā)者就可以實(shí)現(xiàn)更為靈活的運(yùn)行時(shí)虛擬機(jī)監(jiān)控和 Java 類操作了,這樣的特性實(shí)際上提供了一種虛擬機(jī)級(jí)別支持的 AOP 實(shí)現(xiàn)方式,使得開發(fā)者無需對(duì) JDK 做任何升級(jí)和改動(dòng),就可以實(shí)現(xiàn)某些 AOP 的功能了。

在 Java SE 6 里面,instrumentation 包被賦予了更強(qiáng)大的功能:?jiǎn)?dòng)后的 instrument、本地代碼(native code)instrument,以及動(dòng)態(tài)改變 classpath 等等。這些改變,意味著 Java 具有了更強(qiáng)的動(dòng)態(tài)控制、解釋能力,它使得 Java 語(yǔ)言變得更加靈活多變。

在 Java SE6 里面,最大的改變使運(yùn)行時(shí)的 Instrumentation 成為可能。在 Java SE 5 中,Instrument 要求在運(yùn)行前利用命令行參數(shù)或者系統(tǒng)參數(shù)來設(shè)置代理類,在實(shí)際的運(yùn)行之中,虛擬機(jī)在初始化之時(shí)(在絕大多數(shù)的 Java 類庫(kù)被載入之前),instrumentation 的設(shè)置已經(jīng)啟動(dòng),并在虛擬機(jī)中設(shè)置了回調(diào)函數(shù),檢測(cè)特定類的加載情況,并完成實(shí)際工作。但是在實(shí)際的很多的情況下,我們沒有辦法在虛擬機(jī)啟動(dòng)之時(shí)就為其設(shè)定代理,這樣實(shí)際上限制了 instrument 的應(yīng)用。而 Java SE 6 的新特性改變了這種情況,通過 Java Tool API 中的 attach 方式,我們可以很方便地在運(yùn)行過程中動(dòng)態(tài)地設(shè)置加載代理類,以達(dá)到 instrumentation 的目的。

另外,對(duì) native 的 Instrumentation 也是 Java SE 6 的一個(gè)嶄新的功能,這使以前無法完成的功能 —— 對(duì) native 接口的 instrumentation 可以在 Java SE 6 中,通過一個(gè)或者一系列的 prefix 添加而得以完成。

最后,Java SE 6 里的 Instrumentation 也增加了動(dòng)態(tài)添加 class path 的功能。所有這些新的功能,都使得 instrument 包的功能更加豐富,從而使 Java 語(yǔ)言本身更加強(qiáng)大。

上面這段摘自IBM Developers,讓我自己解釋,有點(diǎn)不好解釋,大家看權(quán)威解答就好。

下面這段是來自Java8 API,英文好的可以讀一下。

/**
 * This class provides services needed to instrument Java
 * programming language code.
 * Instrumentation is the addition of byte-codes to methods for the
 * purpose of gathering data to be utilized by tools.
 * Since the changes are purely additive, these tools do not modify
 * application state or behavior.
 * Examples of such benign tools include monitoring agents, profilers,
 * coverage analyzers, and event loggers.
 *
 * <P>
 * There are two ways to obtain an instance of the
 * <code>Instrumentation</code> interface:
 *
 * <ol>
 *   <li><p> When a JVM is launched in a way that indicates an agent
 *     class. In that case an <code>Instrumentation</code> instance
 *     is passed to the <code>premain</code> method of the agent class.
 *     </p></li>
 *   <li><p> When a JVM provides a mechanism to start agents sometime
 *     after the JVM is launched. In that case an <code>Instrumentation</code>
 *     instance is passed to the <code>agentmain</code> method of the
 *     agent code. </p> </li>
 * </ol>
 * <p>
 * These mechanisms are described in the
 * {@linkplain java.lang.instrument package specification}.
 * <p>
 * Once an agent acquires an <code>Instrumentation</code> instance,
 * the agent may call methods on the instance at any time.
 *
 * @since   1.5
 */

知道了這個(gè)類可以在JVM運(yùn)行過程中測(cè)量對(duì)象大小,下面談?wù)勅绾问褂?,這個(gè)Instrumentation接口不太友好,筆者跟蹤了下這個(gè)接口,發(fā)現(xiàn)它的實(shí)現(xiàn)類是在rt.jar包里的,簡(jiǎn)單介紹下rt.jar,大家都知道是極為重要的一個(gè)文件,rt是runtime的縮寫,即運(yùn)行時(shí)的意思。

是java程序在運(yùn)行時(shí)必不可少的文件。里面包含了java程序員常用的包,如java.lang,java.util,java.io,java.net, java.applet等。

也就是說,我們想得到Instrumentation的實(shí)例,必須得在JVM運(yùn)行過程中才能取得,翻開源碼構(gòu)造方法是private類型,沒有任何getInstance的方法,寫這個(gè)類干嘛?

看來這個(gè)只能被JVM自己給初始化了,那么怎么將它自己初始化的東西取出來用呢,唯一能想到的就是javaagent代理,我說這是代理技術(shù),不知道準(zhǔn)不準(zhǔn)確,若不正確請(qǐng)大家指正。

Step1:先創(chuàng)建一個(gè)用于測(cè)試對(duì)象大小的處理類(代理類)

import java.lang.instrument.Instrumentation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Stack;
public class MySizeOf {
    static Instrumentation inst;
    public static void premain(String agentArgs, Instrumentation instP) {
        inst = instP;
    }
    public static long sizeOf(Object o) {
        if(inst == null) {
            throw new IllegalStateException("Can not access instrumentation environment.\n" +
                    "Please check if jar file containing SizeOfAgent class is \n" +
                    "specified in the java's \"-javaagent\" command line argument.");
        }
        return inst.getObjectSize(o);
    }
}

這就是agent的代碼,此時(shí)我們要將上面這個(gè)類編譯后打包為一個(gè)jar文件,并且在其包內(nèi)部的META-INF/MANIFEST.MF文件中增加一行:Premain-Class: MySizeOf代表執(zhí)行代理的全名,這里的類名稱是沒有package的,如果你有package,那么就寫全名,假設(shè)打包完的jar包名稱為agent.jar,打包的過程簡(jiǎn)單說一下,jar命令參考文章最后的Extra部分。

  • jar cf agent.jar MySizeOf.java //將MySizeOf.java打成jar包
  • 修改jar包中的META-INF/MANIFEST.MF文件,增加一行:Premain-Class: MySizeOf,這里的類名稱是沒有package的,如果你有package,那么就寫全名。

Step2:編寫測(cè)試類TestSize

這里我打算測(cè)一下Interger、String、ArrayList、Object以及Long類型的對(duì)象大小。

代碼如下:

public class TestSize {
    public static void main(String []args) {
        System.out.println("一個(gè)Interger對(duì)象大小為:"+MySizeOf.sizeOf(new Integer(1)));
        System.out.println("一個(gè)String對(duì)象大小為:"+MySizeOf.sizeOf(new String("a")));
        System.out.println("一個(gè)String對(duì)象大?。P(guān)閉指針壓縮)為:"+MySizeOf.fullSizeOf(new String("a")));
        System.out.println("一個(gè)char對(duì)象大小為:"+MySizeOf.sizeOf(new char[1]));
        System.out.println("一個(gè)ArrayList對(duì)象大小為:"+MySizeOf.sizeOf(new ArrayList<>()));
        System.out.println("一個(gè)Object對(duì)象大小為:"+MySizeOf.sizeOf(new Object()));
        System.out.println("一個(gè)Long對(duì)象大小為:"+MySizeOf.sizeOf(new Long(10000000000L)));
    }
}

Step3:執(zhí)行TestSize,進(jìn)行測(cè)試

這里需要注意一點(diǎn),這個(gè)Test方法不能在IDE環(huán)境中執(zhí)行,因?yàn)槟銦o法使用Instrumentation的實(shí)例,必須采用古老的javac,java命令先編譯再執(zhí)行,請(qǐng)按照以下步驟執(zhí)行,

// step1,編譯TestSize.java,并將agent.jar包中的Instrumentation的實(shí)例引入ClassPath,這樣執(zhí)行TestSize.java時(shí)才能引用Instrumentation實(shí)例。
javac -classpath agent.jar TestSize.java
//step2,執(zhí)行TestSize,使用-javaagent:agent.jar,意思是使用agent.jar作為代理,用到agent技術(shù)
java -javaagent:agent.jar TestSize  

運(yùn)行結(jié)果:

一個(gè)Interger對(duì)象大小為:16
一個(gè)String對(duì)象大小為:24
一個(gè)String對(duì)象大小(關(guān)閉指針壓縮)為:48
一個(gè)char對(duì)象大小為:24
一個(gè)ArrayList對(duì)象大小為:24
一個(gè)Object對(duì)象大小為:16
一個(gè)Long對(duì)象大小為:24

在網(wǎng)上看到一個(gè)更全面的Agent測(cè)試類,里面提供了不少測(cè)量方法,提供給大家,

public class MySizeOf {
    static Instrumentation inst;
    public static void premain(String agentArgs, Instrumentation instP) {
        inst = instP;
    }
    public static long sizeOf(Object o) {
        if(inst == null) {
            throw new IllegalStateException("Can not access instrumentation environment.\n" +
                    "Please check if jar file containing SizeOfAgent class is \n" +
                    "specified in the java's \"-javaagent\" command line argument.");
        }
        return inst.getObjectSize(o);
    }
    /**
     * 遞歸計(jì)算當(dāng)前對(duì)象占用空間總大小,包括當(dāng)前類和超類的實(shí)例字段大小以及實(shí)例字段引用對(duì)象大小
     */
    public static long fullSizeOf(Object obj) {//深入檢索對(duì)象,并計(jì)算大小
        Map<Object, Object> visited = new IdentityHashMap<Object, Object>();
        Stack<Object> stack = new Stack<Object>();
        long result = internalSizeOf(obj, stack, visited);
        while (!stack.isEmpty()) {//通過棧進(jìn)行遍歷
            result += internalSizeOf(stack.pop(), stack, visited);
        }
        visited.clear();
        return result;
    }
    //判定哪些是需要跳過的
    private static boolean skipObject(Object obj, Map<Object, Object> visited) {
        if (obj instanceof String) {
            if (obj == ((String) obj).intern()) {
                return true;
            }
        }
        return (obj == null) || visited.containsKey(obj);
    }
    private static long internalSizeOf(Object obj, Stack<Object> stack, Map<Object, Object> visited) {
        if (skipObject(obj, visited)) {//跳過常量池對(duì)象、跳過已經(jīng)訪問過的對(duì)象
            return 0;
        }
        visited.put(obj, null);//將當(dāng)前對(duì)象放入棧中
        long result = 0;
        result += sizeOf(obj);
        Class <?>clazz = obj.getClass();
        if (clazz.isArray()) {//如果數(shù)組
            if(clazz.getName().length() != 2) {// skip primitive type array
                int length =  Array.getLength(obj);
                for (int i = 0; i < length; i++) {
                    stack.add(Array.get(obj, i));
                }
            }
            return result;
        }
        return getNodeSize(clazz , result , obj , stack);
    }
    //這個(gè)方法獲取非數(shù)組對(duì)象自身的大小,并且可以向父類進(jìn)行向上搜索
    private static long getNodeSize(Class <?>clazz , long result , Object obj , Stack<Object> stack) {
        while (clazz != null) {
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                if (!Modifier.isStatic(field.getModifiers())) {//這里拋開靜態(tài)屬性
                    if (field.getType().isPrimitive()) {//這里拋開基本關(guān)鍵字(因?yàn)榛娟P(guān)鍵字在調(diào)用java默認(rèn)提供的方法就已經(jīng)計(jì)算過了)
                        continue;
                    }else {
                        field.setAccessible(true);
                        try {
                            Object objectToAdd = field.get(obj);
                            if (objectToAdd != null) {
                                stack.add(objectToAdd);//將對(duì)象放入棧中,一遍彈出后繼續(xù)檢索
                            }
                        } catch (IllegalAccessException ex) {
                            assert false;
                        }
                    }
                }
            }
            clazz = clazz.getSuperclass();//找父類class,直到?jīng)]有父類
        }
        return result;
    }
}

到這里就結(jié)束了,有幾個(gè)疑問,大家有興趣可以關(guān)注下:

1.修改MANIFEST文件應(yīng)該還有其他方法,好像是jar cmf manifest-addition jar-file input-file(s),大家有興趣可以關(guān)注下

2.如何在IDE中實(shí)現(xiàn)以上這些步驟,javac和java畢竟是遠(yuǎn)古時(shí)代的東西了。

3.Instrumentation 的最大作用再說一說,就是類定義動(dòng)態(tài)改變和操作。在 Java SE 5 及其后續(xù)版本當(dāng)中,開發(fā)者可以在一個(gè)普通 Java 程序(帶有 main 函數(shù)的 Java 類)運(yùn)行時(shí),通過 – javaagent參數(shù)指定一個(gè)特定的 jar 文件(包含 Instrumentation 代理)來啟動(dòng) Instrumentation 的代理程序,然后利用Instrumentation的實(shí)現(xiàn)類做一列測(cè)量,這個(gè)有點(diǎn)類似AOP

4.先想這么多,想到更多問題再補(bǔ)充。

Extra:

jar操作指令

操作命令Cool
創(chuàng)建一個(gè)JAR文件jar cf jar-file input-file(s)
查看JAR文件的內(nèi)容jar tf jar-file
導(dǎo)出JAR文件jar xf jar-file
導(dǎo)出JAR文件中制定的文件包jar xf jar-file archived-file(s)
運(yùn)行JAR文件中的應(yīng)用jre -cp app.jar MainClass
運(yùn)行用JAR格式打包的應(yīng)用java -jar app.jar
調(diào)用一個(gè)打包成JAR的applet

方法三

使用JOL 工具來查看一個(gè)對(duì)象的大小和分布

這個(gè)和前兩個(gè)方法不太一樣,是用來測(cè)一個(gè)JVM中對(duì)象的內(nèi)部分布情況的,而且測(cè)得是引用的大小,Object obj中,這個(gè)引用obj也是占大小的。

這個(gè)方法作為拓展即可。

JOL (Java Object Layout) is the tiny toolbox to analyze object layout schemes in JVMs.

These tools are using Unsafe, JVMTI, and Serviceability Agent (SA) heavily to decoder the actual object layout, footprint, and references.

This makes JOL much more accurate than other tools relying on heap dumps, specification assumptions, etc.

該工具官網(wǎng):

http://openjdk.java.NET/projects/code-tools/jol/

下載jar包后保持如下的相對(duì)路徑 和你要測(cè)試的類在一起.

編寫測(cè)試對(duì)象的類:VolatileLong

public final class VolatileLong {
        /**
         * 大小計(jì)算:
         *  long 8 字節(jié)
         * [1]java對(duì)象頭: 32位 :8 byte 64位:12 byte
         * 所以總共: 6 個(gè)填充 * 8 byte + 8 (value) + 8 (對(duì)象頭) = 64 byte
         *  還有采用如下方式的
         *  long p1, p2, p3, p4, p5, p6, p7; // cache line padding  -> 7 *8 = 56 字節(jié)
         *  long value;  ->  8 字節(jié)
         *  long p8, p9, p10, p11, p12, p13, p14; // cache line padding -> 7*8 = 56 字節(jié)
         *
         *  java.util.concurrent.Exchanger.Slot<V>
         *          // Improve likelihood of isolation on <= 64 byte cache lines
         *  long q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe;  15 * 8
         *  不知道為啥是這樣實(shí)現(xiàn):因?yàn)楦割愡€有一個(gè)Long值 所以總的來說已經(jīng)超過128了
         *
         */
        public volatile long value = 0L;
        public long p1, p2, p3, p4, p5, p6; // comment out
        //objectsize = 6*8 + 8 + 4 =
}

執(zhí)行下面指令:

java -jar jol-cli-0.9-full.jar internals -cp . VolatileLong

//jar包必須帶上全路徑,先把class文件編譯出來,然后再執(zhí)行,因?yàn)榇嗣钪唤邮躢lass方式,若在IDE中測(cè)試,去掉報(bào)名,不然會(huì)報(bào)找不到類的錯(cuò)誤,如下

java.lang.NoClassDefFoundError: ObjectLoc (wrong name: com/pingan/jvm/objectsize/ObjectLoc)
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:348)
        at org.openjdk.jol.util.ClassUtils.loadClass(ClassUtils.java:70)
        at org.openjdk.jol.operations.ClasspathedOperation.run(ClasspathedOperation.java:76)
        at org.openjdk.jol.Main.main(Main.java:60)

運(yùn)行結(jié)果:

VolatileLong object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           85 07 02 f8 (10000101 00000111 00000010 11111000) (-134084731)
     12     4        (alignment/padding gap)                  
     16     8   long VolatileLong.value                        0
     24     8   long VolatileLong.p1                           0
     32     8   long VolatileLong.p2                           0
     40     8   long VolatileLong.p3                           0
     48     8   long VolatileLong.p4                           0
     56     8   long VolatileLong.p5                           0
     64     8   long VolatileLong.p6                           0
Instance size: 72 bytes
Space losses: 4 bytes internal + 0 bytes external = 4 bytes total

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 高分面試分析jvm如何實(shí)現(xiàn)多態(tài)

    高分面試分析jvm如何實(shí)現(xiàn)多態(tài)

    這篇文章主要介紹了講解了在面試中jvm如何實(shí)現(xiàn)多態(tài),怎樣回答才能得到高分的問題分析,有需要的朋友可以借鑒參考下,祝大家早日升職加薪多多進(jìn)步
    2022-01-01
  • Java中的接口及其應(yīng)用場(chǎng)景解讀

    Java中的接口及其應(yīng)用場(chǎng)景解讀

    這篇文章主要介紹了Java中的接口及其應(yīng)用場(chǎng)景解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Java詳解如何將excel數(shù)據(jù)轉(zhuǎn)為樹形

    Java詳解如何將excel數(shù)據(jù)轉(zhuǎn)為樹形

    在平常的辦公工作中,excel數(shù)據(jù)的操作是最常見的需求,今天就來看一下通過Java如何來實(shí)現(xiàn)將excel數(shù)據(jù)轉(zhuǎn)為樹形,感興趣的朋友可以了解下
    2022-08-08
  • SpringBoot使用Captcha生成驗(yàn)證碼

    SpringBoot使用Captcha生成驗(yàn)證碼

    這篇文章主要介紹了SpringBoot如何使用Captcha生成驗(yàn)證碼,幫助大家更好的理解和學(xué)習(xí)使用SpringBoot,感興趣的朋友可以了解下
    2021-04-04
  • MyBatis實(shí)現(xiàn)多表聯(lián)查的詳細(xì)代碼

    MyBatis實(shí)現(xiàn)多表聯(lián)查的詳細(xì)代碼

    這篇文章主要介紹了MyBatis如何實(shí)現(xiàn)多表聯(lián)查,通過實(shí)例代碼給大家介紹使用映射配置文件實(shí)現(xiàn)多表聯(lián)查,使用注解的方式實(shí)現(xiàn)多表聯(lián)查,需要的朋友可以參考下
    2022-08-08
  • JAVA簡(jiǎn)單工廠模式(從現(xiàn)實(shí)生活角度理解代碼原理)

    JAVA簡(jiǎn)單工廠模式(從現(xiàn)實(shí)生活角度理解代碼原理)

    本文主要介紹了JAVA簡(jiǎn)單工廠模式(從現(xiàn)實(shí)生活角度理解代碼原理)的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來看下吧
    2017-03-03
  • 在IDEA中配置tomcat并創(chuàng)建tomcat項(xiàng)目的圖文教程

    在IDEA中配置tomcat并創(chuàng)建tomcat項(xiàng)目的圖文教程

    這篇文章主要介紹了在IDEA中配置tomcat并創(chuàng)建tomcat項(xiàng)目的圖文教程,需要的朋友可以參考下
    2020-07-07
  • JavaSE實(shí)現(xiàn)文件壓縮與解壓縮的技巧分享

    JavaSE實(shí)現(xiàn)文件壓縮與解壓縮的技巧分享

    我們?cè)谌粘?shí)際開發(fā)中,對(duì)于文件壓縮和解壓縮場(chǎng)景,是非常常見的操作,本文詳細(xì)介紹JavaSE中文件壓縮和解壓縮的實(shí)現(xiàn)方法,包括源代碼解析、應(yīng)用場(chǎng)景案例、優(yōu)缺點(diǎn)分析、案例演示、文末總結(jié)等等,請(qǐng)同學(xué)們耐心閱讀
    2024-03-03
  • MybatisPlus自動(dòng)填充創(chuàng)建(更新)時(shí)間問題

    MybatisPlus自動(dòng)填充創(chuàng)建(更新)時(shí)間問題

    在開發(fā)數(shù)據(jù)庫(kù)相關(guān)應(yīng)用時(shí),手動(dòng)設(shè)置創(chuàng)建和更新時(shí)間會(huì)導(dǎo)致代碼冗余,MybatisPlus提供了自動(dòng)填充功能,通過實(shí)現(xiàn)MetaObjectHandler接口并重寫insertFill、updateFill方法,可以自動(dòng)維護(hù)創(chuàng)建時(shí)間、更新時(shí)間等字段,極大簡(jiǎn)化了代碼,這不僅提高了開發(fā)效率,也保證了數(shù)據(jù)的可追溯性
    2024-09-09
  • Java實(shí)現(xiàn)DFA算法對(duì)敏感詞、廣告詞過濾功能示例

    Java實(shí)現(xiàn)DFA算法對(duì)敏感詞、廣告詞過濾功能示例

    本篇文章主要介紹了Java實(shí)現(xiàn)DFA算法對(duì)敏感詞、廣告詞過濾功能示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11

最新評(píng)論