Class and object initialization-part1

本文深入探讨Java中的初始化概念,包括类和对象的初始化过程。文章通过实例解释了默认初始化、显式初始化及类块初始化等不同类型的初始化方式,并介绍了它们在Java虚拟机中的实现原理。

This article marks a milestone in Java 101's exploration of client-side Java, as well as the one year anniversary of the series. Jeff begins moving away from simpler Java language concepts toward more advanced theories -- and toward a grand tour of Java's standard class library. Begin the journey this month by learning all about Java initialization.

Initialization prepares classes and objects for use during a program's execution. Although we tend to think of initialization in terms of assigning values to variables, initialization is so much more. For example, initialization might involve opening a file and reading its contents into a memory buffer, registering a database driver, preparing a memory buffer to hold an image's contents, acquiring the resources necessary for playing a video, and so on. Think of anything that prepares a class or an object for use in a program as initialization.

Java supports initialization via language features collectively known as initializers.Because Java handles class initialization differently from object initialization, and because classes initialize before objects, we first explore class initialization and class-oriented initializers. Later, we explore object initialization and object-oriented initializers.

Class initialization

A program consists of classes. Before a Java application runs, Java's class loader loads its starting class -- the class with a public static void main(String [] args) method -- and Java's byte code verifier verifies the class. Then that class initializes. The simplest kind of class initialization is automatic initialization of class fields to default values. Listing 1 demonstrates that initialization:

Listing 1. ClassInitializationDemo1.java

// ClassInitializationDemo1.java
class ClassInitializationDemo1
{
   static boolean b;
   static byte by;
   static char c;
   static double d;
   static float f;
   static int i;
   static long l;
   static short s;
   static String st;
   public static void main (String [] args)
   {
      System.out.println ("b = " + b);
      System.out.println ("by = " + by);
      System.out.println ("c = " + c);
      System.out.println ("d = " + d);
      System.out.println ("f = " + f);
      System.out.println ("i = " + i);
      System.out.println ("l = " + l);
      System.out.println ("s = " + s);
      System.out.println ("st = " + st);
   }
}

ClassInitializationDemo1's static keyword introduces a variety of class fields. As you can see, no explicit values assign to any of those fields. And yet, when you runClassInitializationDemo1, you see the following output:

b = false
by = 0
c =  
d = 0.0
f = 0.0
i = 0
l = 0
s = 0
st = null

The false00.0, and null values are the type-oriented representations of default values. They represent the result of all bits automatically set to zero in each class field. And what automatically set those bits to zero? The JVM, after a class is verified. (Note: In the preceding output, you do not see a value beside c = because the JVM interprets c's default value as the nondisplayable null value.)

Class field initializers

After automatic initialization, the next simplest kind of class initialization is the explicit initialization of class fields to values. Each class field explicitly initializes to a value via a class field initializer. Listing 2 illustrates several class field initializers:

Listing 2. ClassInitializationDemo2.java

// ClassInitializationDemo2.java
class ClassInitializationDemo2
{
   static boolean b = true;
   static byte by = 1;
   static char c = 'A';
   static double d = 1.2;
   static float f = 3.4f;
   static int i = 2;
   static long l = 3;
   static short s = 4;
   static String st = "abc";
   public static void main (String [] args)
   {
      System.out.println ("b = " + b);
      System.out.println ("by = " + by);
      System.out.println ("c = " + c);
      System.out.println ("d = " + d);
      System.out.println ("f = " + f);
      System.out.println ("i = " + i);
      System.out.println ("l = " + l);
      System.out.println ("s = " + s);
      System.out.println ("st = " + st);
   }
}

In contrast to ClassInitializationDemo1, in ClassInitializationDemo2 a class field initializer explicitly assigns a nondefault value to each class field. Simply put, a class field initializer consists of the assignment operator (=) and an expression that the JVM evaluates after a class loads and before any of that class's developer-specified methods execute. The assignment operator assigns the expression's value to the associated class field. When run, ClassInitializationDemo2 produces the following output:

b = true
by = 1
c = A
d = 1.2
f = 3.4
i = 2
l = 3
s = 4
st = abc

Although the output is as expected, what executes the class field initializers that explicitly initialize ClassInitializationDemo2's class fields? The answer: After the JVM zeroes the bits in all class fields, it calls a special JVM-level method to execute the byte code instructions that comprise the class's class field initializers. That method is known as <clinit>.

When you compile a class containing at least one class field initializer, the compiler generates code for <clinit>. After the JVM's class loader loads the class, after the byte code verifier verifies the class's byte codes, and after the JVM allocates memory for the class fields and zeroes all bits in those class fields, the JVM calls the class's<clinit> method (if present). The <clinit> method's byte code instructions execute all class field initializers. To see what those byte code instructions look like for the above ClassInitializationDemo2 class, check out Listing 3:

Listing 3. ClassInitializationDemo2's <clinit> method

 0   iconst_1
 1   putstatic ClassInitializationDemo2/b Z          // boolean b = true;
 4   iconst_1
 5   putstatic ClassInitializationDemo2/by B         // byte by = 1;
 8   bipush 65
10   putstatic ClassInitializationDemo2/c C          // char c = 'A';
13   ldc2_w #1.200000
16   putstatic ClassInitializationDemo2/d D          // double d = 1.2;
19   ldc #3.400000
21   putstatic ClassInitializationDemo2/f F          // float f = 3.4f; 
24   iconst_2
25   putstatic ClassInitializationDemo2/i I          // int i = 2;
28   ldc2_w #3
31   putstatic ClassInitializationDemo2/l J          // long l = 3; 
34   iconst_4
35   putstatic ClassInitializationDemo2/s S          // short s = 4;
38   ldc "abc"
40   putstatic ClassInitializationDemo2/st Ljava/lang/String;  // String st = "abc";
43   return

Listing 3 presents some insight into how ClassInitializationDemo2's <clinit> method works. Each line presents a number and a byte code instruction. The number represents the instruction's zero-based address and is not important to this discussion. The first instruction, iconst_1, pushes integer constant 1 onto a stack, and the second instruction, putstatic ClassInitializationDemo2/b Z, pops that constant from the stack and assigns it to boolean class field b. (At the JVM level, at least with Sun's JVM, the Boolean true value is represented as integer constant 1.) The Z appearing to the right of the putstatic instruction identifies the type of b as Boolean. Similarly, Bidentifies the byte type, C identifies the character type, D identifies the double-precision floating-point type, F identifies the floating-point type, J identifies the long integer type, and S identifies the short integer type. The bipushldc2_wldc, and othericonst instructions push other constants onto the stack, and their respective putstaticinstructions pop those values from the stack before assigning them to various class fields. The final return instruction causes execution to leave the <clinit> method. At that point, the main() method starts to execute.

Some programs require class fields to refer to previously declared class fields. Java supports that activity by letting you specify the name of a previously declared class field in the expression portion of a subsequently declared class field's class field initializer, as Listing 4 demonstrates:

Listing 4. ClassInitializationDemo3.java

// ClassInitializationDemo3.java
class ClassInitializationDemo3
{
   static int first = 3;
   static int second = 1 + first;
   public static void main (String [] args)
   {
      System.out.println ("first = " + first);
      System.out.println ("second = " + second);
   }
}

ClassInitializationDemo3 declares class field first and explicitly assigns 3 to that field. Then, ClassInitializationDemo3 declares class field second and refers to first in second's class initializer expression. When you run the program, you see the following output:

first = 3
second = 4

If you examine the byte code instructions for ClassInitializationDemo3's <clinit>method, you see something similar to Listing 5:

Listing 5. ClassInitializationDemo3's <clinit> method

 0   iconst_3
 1   putstatic ClassInitializationDemo3/first I   // first = 3;
 4   iconst_1
 5   getstatic ClassInitializationDemo3/first I
 8   iadd
 9   putstatic ClassInitializationDemo3/second I  // second = 1 + first;
12   return

Listing 5 shows byte code instructions that assign 3 to first and add constant 1 tofirst's contents. The result of that addition ends up in a temporary stack-based variable. The instructions subsequently assign the contents of the temporary stack-based variable to second.

Although a subsequently declared class field can refer to a previously declared class field, the reverse is not true: You cannot declare a class field initializer that refers to a class field declared later in source code. In other words, Java does not permit forward references with class field initializers, as the following code fragment demonstrates:

static int second = 1 + first;
static int first = 3;

When the compiler encounters either the code above or another forward reference code fragment during compilation, it generates an error message because the developer's intention is unclear. Should the compiler regard first as containing 0, which results in second initializing to 1, or should the compiler regard first as containing 3, which results in second initializing to 4? To prevent that confusion, Java prohibits class field initializers from making forward references to other class fields.

Class block initializers

Although sufficient for class field initialization, class field initializers prove inadequate for more complex class initialization. For example, suppose you need to read a file's contents into a buffer before the main() method executes. What do you do? Java meets that challenge by providing the class block initializer. A class block initializer consists of keyword static followed by an open brace character ({), initialization code, and a close brace character (}). Furthermore, a class block initializer appears within a class, but not within any of that class's methods, as Listing 6 demonstrates:

Listing 6. ClassInitializationDemo4.java

// ClassInitializationDemo4.java
import java.io.*;
class ClassInitializationDemo4
{
   static String [] filenames;
   static
   {
      System.out.println ("Acquiring filenames");
      filenames = new File (".").list ();
      System.out.println ("Filenames acquired");
   }
   public static void main (String [] args)
   {
      System.out.println ("Displaying filenames\n");
      for (int i = 0; i < filenames.length; i++)
           System.out.println (filenames [i]);
   }
}

ClassInitializationDemo4 declares a filenames array field variable and then introduces a class block initializer. That initializer displays a status message, obtains a list of all filenames for those files that appear in the current directory, and displays a second status message. All that activity takes place before the main() method executes. Whenmain() executes, a status message displays, along with a list of filenames. The result resembles the following output:

Acquiring filenames
Filenames acquired
Displaying filenames
ClassInitializationDemo4.java
ClassInitializationDemo4.class

In addition to placing the class field initializers' byte code instructions in a class's<clinit> method, the compiler places the byte code instructions of each encountered class block initializer in that same method. The compiler places these instructions in the <clinit> method according to a specific order. Because the compiler compiles a class in a top-to-bottom fashion, it places in the <clinit> method, in a top-to-bottom order, the equivalent byte code instructions to each encountered class field initializer and class block initializer. Refer back to Listing 6: The compiler places the class block initializer's byte code instructions in ClassInitializationDemo4's <clinit> method. If that class specified a class field initializer for its filenames class field, the byte code instructions comprising that class field initializer would appear before the class block initializer's byte code instructions in the <clinit> method.

原文链接:http://www.javaworld.com/article/2075796/java-platform/java-101--class-and-object-initialization.html

"E:\buka resource\Tomcat 9.0\Tomcat 9.0\bin\catalina.bat" run [2025-09-15 02:17:00,236] Artifact 9.14_homework:war: Waiting for server connection to start artifact deployment... Using CATALINA_BASE: "C:\Users\asus\AppData\Local\JetBrains\IntelliJIdea2021.1\tomcat\571f7d60-cc7b-4657-a774-118f50351c2c" Using CATALINA_HOME: "E:\buka resource\Tomcat 9.0\Tomcat 9.0" Using CATALINA_TMPDIR: "E:\buka resource\Tomcat 9.0\Tomcat 9.0\temp" Using JRE_HOME: "C:\Program Files\Java\jdk1.8.0_211" Using CLASSPATH: "E:\buka resource\Tomcat 9.0\Tomcat 9.0\bin\bootstrap.jar;E:\buka resource\Tomcat 9.0\Tomcat 9.0\bin\tomcat-juli.jar" Using CATALINA_OPTS: "" Connected to the target VM, address: '127.0.0.1:59280', transport: 'socket' 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Server.服务器版本: Apache Tomcat/9.0.54 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 服务器构建: Sep 28 2021 13:51:49 UTC 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 服务器版本号: 9.0.54.0 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 操作系统名称: Windows 10 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log OS.版本: 10.0 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 架构: amd64 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Java 环境变量: C:\Program Files\Java\jdk1.8.0_211\jre 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log Java虚拟机版本: 1.8.0_211-b12 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log JVM.供应商: Oracle Corporation 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: C:\Users\asus\AppData\Local\JetBrains\IntelliJIdea2021.1\tomcat\571f7d60-cc7b-4657-a774-118f50351c2c 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: E:\buka resource\Tomcat 9.0\Tomcat 9.0 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djava.util.logging.config.file=C:\Users\asus\AppData\Local\JetBrains\IntelliJIdea2021.1\tomcat\571f7d60-cc7b-4657-a774-118f50351c2c\conf\logging.properties 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:59280,suspend=y,server=n 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -javaagent:C:\Users\asus\AppData\Local\JetBrains\IntelliJIdea2021.1\captureAgent\debugger-agent.jar 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dcom.sun.management.jmxremote= 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dcom.sun.management.jmxremote.port=1099 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dcom.sun.management.jmxremote.ssl=false 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dcom.sun.management.jmxremote.password.file=C:\Users\asus\AppData\Local\JetBrains\IntelliJIdea2021.1\tomcat\571f7d60-cc7b-4657-a774-118f50351c2c\jmxremote.password 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dcom.sun.management.jmxremote.access.file=C:\Users\asus\AppData\Local\JetBrains\IntelliJIdea2021.1\tomcat\571f7d60-cc7b-4657-a774-118f50351c2c\jmxremote.access 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djava.rmi.server.hostname=127.0.0.1 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djdk.tls.ephemeralDHKeySize=2048 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dignore.endorsed.dirs= 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dcatalina.base=C:\Users\asus\AppData\Local\JetBrains\IntelliJIdea2021.1\tomcat\571f7d60-cc7b-4657-a774-118f50351c2c 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Dcatalina.home=E:\buka resource\Tomcat 9.0\Tomcat 9.0 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.startup.VersionLoggerListener.log 命令行参数: -Djava.io.tmpdir=E:\buka resource\Tomcat 9.0\Tomcat 9.0\temp 15-Sep-2025 14:17:01.205 信息 [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent 在java.library.path:[C:\Program Files\Java\jdk1.8.0_211\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Microsoft SQL Server\150\Tools\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;C:\Program Files\dotnet\;D:\Windows Kits\10\Windows Performance Toolkit\;C:\Program Files\Bandizip\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;E:\MYSql\mysql-8.0.30-winx64\bin;D:\app\mysql xx\bc\bin;C:\Program Files\NVIDIA Corporation\NVIDIA App\NvDLISR;C:\Users\asus\AppData\Local\Microsoft\WindowsApps;C:\Users\asus\.dotnet\tools;D:\app\idea\IntelliJ IDEA 2023.3.4\bin;;;.]上找不到基于APR的Apache Tomcat本机库,该库允许在生产环境中获得最佳性能 15-Sep-2025 14:17:01.380 信息 [main] org.apache.coyote.AbstractProtocol.init 初始化协议处理器 ["http-nio-8080"] 15-Sep-2025 14:17:01.380 信息 [main] org.apache.catalina.startup.Catalina.load 服务器在[333]毫秒内初始化 15-Sep-2025 14:17:01.411 信息 [main] org.apache.catalina.core.StandardService.startInternal 正在启动服务[Catalina] 15-Sep-2025 14:17:01.411 信息 [main] org.apache.catalina.core.StandardEngine.startInternal 正在启动 Servlet 引擎:[Apache Tomcat/9.0.54] 15-Sep-2025 14:17:01.417 信息 [main] org.apache.coyote.AbstractProtocol.start 开始协议处理句柄["http-nio-8080"] 15-Sep-2025 14:17:01.427 信息 [main] org.apache.catalina.startup.Catalina.start [40]毫秒后服务器启动 Connected to server [2025-09-15 02:17:01,807] Artifact 9.14_homework:war: Artifact is being deployed, please wait... 15-Sep-2025 14:17:04.092 信息 [RMI TCP Connection(3)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的JAR可以缩短启动时间和JSP编译时间。 14:17:04.188 [RMI TCP Connection(3)-127.0.0.1] INFO org.springframework.web.context.ContextLoader - Root WebApplicationContext: initialization started 14:17:04.267 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.web.context.support.XmlWebApplicationContext - Refreshing Root WebApplicationContext 14:17:04.457 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [E:\buka resource\Tomcat 9.0\Tomcat 9.0\webapps\ROOT\WEB-INF\classes\com\buka\service\ClassService.class] 14:17:04.457 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [E:\buka resource\Tomcat 9.0\Tomcat 9.0\webapps\ROOT\WEB-INF\classes\com\buka\service\StuService.class] 14:17:04.489 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 11 bean definitions from class path resource [application.xml] 14:17:04.537 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor' 14:17:04.584 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.mybatis.spring.mapper.MapperScannerConfigurer#0' 14:17:04.631 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.apache.ibatis.logging.LogFactory - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter. 14:17:04.631 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.mybatis.spring.mapper.ClassPathMapperScanner - Identified candidate component class: file [E:\buka resource\Tomcat 9.0\Tomcat 9.0\webapps\ROOT\WEB-INF\classes\com\buka\dao\ClassDao.class] 14:17:04.631 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.mybatis.spring.mapper.ClassPathMapperScanner - Identified candidate component class: file [E:\buka resource\Tomcat 9.0\Tomcat 9.0\webapps\ROOT\WEB-INF\classes\com\buka\dao\Studao.class] 14:17:04.631 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.mybatis.spring.mapper.ClassPathMapperScanner - Creating MapperFactoryBean with name 'classDao' and 'com.buka.dao.ClassDao' mapperInterface 14:17:04.631 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.mybatis.spring.mapper.ClassPathMapperScanner - Creating MapperFactoryBean with name 'studao' and 'com.buka.dao.Studao' mapperInterface 14:17:04.647 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.support.PropertySourcesPlaceholderConfigurer#0' 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [java:comp/env/jdbc.driver] 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiLocatorDelegate - Converted JNDI name [java:comp/env/jdbc.driver] not found - trying original name [jdbc.driver]. javax.naming.NameNotFoundException: 名称[jdbc.driver]未在此上下文中绑定。找不到[jdbc.driver]。 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [jdbc.driver] 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiPropertySource - JNDI lookup for name [jdbc.driver] threw NamingException with message: 名称[jdbc.driver]未在此上下文中绑定。找不到[jdbc.driver]。. Returning null. 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Found key 'jdbc.driver' in PropertySource 'localProperties' with value of type String 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [java:comp/env/jdbc.password] 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiLocatorDelegate - Converted JNDI name [java:comp/env/jdbc.password] not found - trying original name [jdbc.password]. javax.naming.NameNotFoundException: 名称[jdbc.password]未在此上下文中绑定。找不到[jdbc.password]。 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [jdbc.password] 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiPropertySource - JNDI lookup for name [jdbc.password] threw NamingException with message: 名称[jdbc.password]未在此上下文中绑定。找不到[jdbc.password]。. Returning null. 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Found key 'jdbc.password' in PropertySource 'localProperties' with value of type String 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [java:comp/env/jdbc.url] 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiLocatorDelegate - Converted JNDI name [java:comp/env/jdbc.url] not found - trying original name [jdbc.url]. javax.naming.NameNotFoundException: 名称[jdbc.url]未在此上下文中绑定。找不到[jdbc.url]。 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [jdbc.url] 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiPropertySource - JNDI lookup for name [jdbc.url] threw NamingException with message: 名称[jdbc.url]未在此上下文中绑定。找不到[jdbc.url]。. Returning null. 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Found key 'jdbc.url' in PropertySource 'localProperties' with value of type String 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [java:comp/env/jdbc.username] 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiLocatorDelegate - Converted JNDI name [java:comp/env/jdbc.username] not found - trying original name [jdbc.username]. javax.naming.NameNotFoundException: 名称[jdbc.username]未在此上下文中绑定。找不到[jdbc.username]。 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [jdbc.username] 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiPropertySource - JNDI lookup for name [jdbc.username] threw NamingException with message: 名称[jdbc.username]未在此上下文中绑定。找不到[jdbc.username]。. Returning null. 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Found key 'jdbc.username' in PropertySource 'localProperties' with value of type String 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor' 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory' 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor' 14:17:04.663 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor' 14:17:04.679 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.ui.context.support.UiApplicationContextUtils - Unable to locate ThemeSource with name 'themeSource': using default [org.springframework.ui.context.support.ResourceBundleThemeSource@3a0a0d1e] 14:17:04.679 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'classService' 14:17:04.710 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'classDao' 14:17:04.726 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'sqlsessionFactory' 14:17:04.726 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'dataSource' Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter. 14:17:04.901 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.mybatis.spring.SqlSessionFactoryBean - Parsed configuration file: 'class path resource [mybatis-config.xml]' 14:17:04.965 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.mybatis.spring.SqlSessionFactoryBean - Parsed mapper file: 'file [E:\buka resource\Tomcat 9.0\Tomcat 9.0\webapps\ROOT\WEB-INF\classes\mapper\ClassMapper.xml]' 14:17:04.965 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.mybatis.spring.SqlSessionFactoryBean - Parsed mapper file: 'file [E:\buka resource\Tomcat 9.0\Tomcat 9.0\webapps\ROOT\WEB-INF\classes\mapper\StuMapper.xml]' 14:17:04.981 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'stuService' 14:17:04.981 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'studao' 14:17:05.020 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [java:comp/env/spring.liveBeansView.mbeanDomain] 14:17:05.020 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiLocatorDelegate - Converted JNDI name [java:comp/env/spring.liveBeansView.mbeanDomain] not found - trying original name [spring.liveBeansView.mbeanDomain]. javax.naming.NameNotFoundException: 名称[spring.liveBeansView.mbeanDomain]未在此上下文中绑定。找不到[spring.liveBeansView.mbeanDomain]。 14:17:05.020 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [spring.liveBeansView.mbeanDomain] 14:17:05.020 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.jndi.JndiPropertySource - JNDI lookup for name [spring.liveBeansView.mbeanDomain] threw NamingException with message: 名称[spring.liveBeansView.mbeanDomain]未在此上下文中绑定。找不到[spring.liveBeansView.mbeanDomain]。. Returning null. 14:17:05.020 [RMI TCP Connection(3)-127.0.0.1] INFO org.springframework.web.context.ContextLoader - Root WebApplicationContext initialized in 832 ms 14:17:05.028 [RMI TCP Connection(3)-127.0.0.1] DEBUG org.springframework.web.filter.CharacterEncodingFilter - Filter 'charset' configured for use [2025-09-15 02:17:05,044] Artifact 9.14_homework:war: Artifact is deployed successfully [2025-09-15 02:17:05,044] Artifact 9.14_homework:war: Deploy took 3,237 milliseconds 14:17:06.043 [http-nio-8080-exec-2] INFO org.springframework.web.servlet.DispatcherServlet - Initializing Servlet 'springMVC' 14:17:06.043 [http-nio-8080-exec-2] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [java:comp/env/spring.profiles.active] 14:17:06.043 [http-nio-8080-exec-2] DEBUG org.springframework.jndi.JndiLocatorDelegate - Converted JNDI name [java:comp/env/spring.profiles.active] not found - trying original name [spring.profiles.active]. javax.naming.NameNotFoundException: 名称[spring.profiles.active]未在此上下文中绑定。找不到[spring.profiles.active]。 14:17:06.043 [http-nio-8080-exec-2] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [spring.profiles.active] 14:17:06.043 [http-nio-8080-exec-2] DEBUG org.springframework.jndi.JndiPropertySource - JNDI lookup for name [spring.profiles.active] threw NamingException with message: 名称[spring.profiles.active]未在此上下文中绑定。找不到[spring.profiles.active]。. Returning null. 14:17:06.043 [http-nio-8080-exec-2] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [java:comp/env/spring.profiles.default] 14:17:06.043 [http-nio-8080-exec-2] DEBUG org.springframework.jndi.JndiLocatorDelegate - Converted JNDI name [java:comp/env/spring.profiles.default] not found - trying original name [spring.profiles.default]. javax.naming.NameNotFoundException: 名称[spring.profiles.default]未在此上下文中绑定。找不到[spring.profiles.default]。 14:17:06.043 [http-nio-8080-exec-2] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [spring.profiles.default] 14:17:06.043 [http-nio-8080-exec-2] DEBUG org.springframework.jndi.JndiPropertySource - JNDI lookup for name [spring.profiles.default] threw NamingException with message: 名称[spring.profiles.default]未在此上下文中绑定。找不到[spring.profiles.default]。. Returning null. 14:17:06.043 [http-nio-8080-exec-2] DEBUG org.springframework.web.context.support.XmlWebApplicationContext - Refreshing WebApplicationContext for namespace 'springMVC-servlet' 14:17:06.073 [http-nio-8080-exec-2] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [E:\buka resource\Tomcat 9.0\Tomcat 9.0\webapps\ROOT\WEB-INF\classes\com\buka\controller\ClassController.class] 14:17:06.073 [http-nio-8080-exec-2] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [E:\buka resource\Tomcat 9.0\Tomcat 9.0\webapps\ROOT\WEB-INF\classes\com\buka\controller\StuController.class] 14:17:06.120 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 26 bean definitions from class path resource [springmvc-config.xml] 14:17:06.120 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor' 14:17:06.170 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor' 14:17:06.170 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory' 14:17:06.170 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor' 14:17:06.170 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor' 14:17:06.170 [http-nio-8080-exec-2] DEBUG org.springframework.ui.context.support.UiApplicationContextUtils - Unable to locate ThemeSource with name 'themeSource': using default [org.springframework.ui.context.support.DelegatingThemeSource@2e74de95] 14:17:06.170 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'classController' 14:17:06.170 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'stuController' 14:17:06.170 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'mvcContentNegotiationManager' 14:17:06.183 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping' 14:17:06.231 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'mvcCorsConfigurations' 14:17:06.231 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.web.servlet.handler.MappedInterceptor#0' 14:17:06.231 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.format.support.FormattingConversionServiceFactoryBean#0' 14:17:06.320 [http-nio-8080-exec-2] DEBUG _org.springframework.web.servlet.HandlerMapping.Mappings - c.b.c.ClassController: { [/menu]}: index(Clazz,ModelAndView) { [/addClass]}: addClass(Clazz,ModelAndView) { [/]}: home() 14:17:06.325 [http-nio-8080-exec-2] DEBUG _org.springframework.web.servlet.HandlerMapping.Mappings - c.b.c.StuController: { [/addStu]}: addStu(Student,ModelAndView) 14:17:06.325 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - 4 mappings in 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping' 14:17:06.325 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter' 14:17:06.373 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - ControllerAdvice beans: none 14:17:06.420 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'mvcUriComponentsContributor' 14:17:06.420 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - ControllerAdvice beans: none 14:17:06.420 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0' 14:17:06.436 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - ControllerAdvice beans: none 14:17:06.436 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0' 14:17:06.436 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0' 14:17:06.436 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping' 14:17:06.452 [http-nio-8080-exec-2] DEBUG _org.springframework.web.servlet.HandlerMapping.Mappings - 'org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping' {} 14:17:06.452 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter' 14:17:06.452 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter' 14:17:06.452 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'localeResolver' 14:17:06.452 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'themeResolver' 14:17:06.452 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'viewNameTranslator' 14:17:06.452 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'flashMapManager' 14:17:06.452 [http-nio-8080-exec-2] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'multipartResolver' 14:17:06.468 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.DispatcherServlet - Detected CommonsMultipartResolver 14:17:06.468 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.DispatcherServlet - Detected AcceptHeaderLocaleResolver 14:17:06.468 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.DispatcherServlet - Detected FixedThemeResolver 14:17:06.468 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.DispatcherServlet - Detected org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator@2bd4fa16 14:17:06.468 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.DispatcherServlet - Detected org.springframework.web.servlet.support.SessionFlashMapManager@53592927 14:17:06.468 [http-nio-8080-exec-2] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [java:comp/env/spring.liveBeansView.mbeanDomain] 14:17:06.468 [http-nio-8080-exec-2] DEBUG org.springframework.jndi.JndiLocatorDelegate - Converted JNDI name [java:comp/env/spring.liveBeansView.mbeanDomain] not found - trying original name [spring.liveBeansView.mbeanDomain]. javax.naming.NameNotFoundException: 名称[spring.liveBeansView.mbeanDomain]未在此上下文中绑定。找不到[spring.liveBeansView.mbeanDomain]。 14:17:06.468 [http-nio-8080-exec-2] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [spring.liveBeansView.mbeanDomain] 14:17:06.468 [http-nio-8080-exec-2] DEBUG org.springframework.jndi.JndiPropertySource - JNDI lookup for name [spring.liveBeansView.mbeanDomain] threw NamingException with message: 名称[spring.liveBeansView.mbeanDomain]未在此上下文中绑定。找不到[spring.liveBeansView.mbeanDomain]。. Returning null. 14:17:06.468 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.DispatcherServlet - enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data 14:17:06.468 [http-nio-8080-exec-2] INFO org.springframework.web.servlet.DispatcherServlet - Completed initialization in 425 ms 14:17:06.492 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.DispatcherServlet - GET "/menu", parameters={} 14:17:06.496 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped to com.buka.controller.ClassController#index(Clazz, ModelAndView) Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@50162767] was not registered for synchronization because synchronization is not active 14:17:06.548 [http-nio-8080-exec-2] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource 14:17:06.594 [http-nio-8080-exec-2] INFO com.alibaba.druid.pool.DruidDataSource - {dataSource-1} inited JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@d2e8721] will not be managed by Spring ==> Preparing: select cid,cname,teacher from class ==> Parameters: <== Columns: cid, cname, teacher <== Row: 1, 1班, zhangsan <== Row: 19, 2班, lisi <== Total: 2 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@50162767] 14:17:07.225 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.view.JstlView - View name 'menu.jsp', model {clazz=Clazz{cid=0, cname='null', teacher='null'}, org.springframework.validation.BindingResult.clazz=org.springframework.validation.BeanPropertyBindingResult: 0 errors, modelAndView=ModelAndView [view="menu.jsp"; model={classist=[Clazz{cid=1, cname='1班', teacher='zhangsan'}, Clazz{cid=19, cname='2班', teacher='lisi'}]}], org.springframework.validation.BindingResult.modelAndView=org.springframework.validation.BeanPropertyBindingResult: 0 errors, classist=[Clazz{cid=1, cname='1班', teacher='zhangsan'}, Clazz{cid=19, cname='2班', teacher='lisi'}]} 14:17:07.243 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.view.JstlView - Forwarding to [menu.jsp] 14:17:07.370 [http-nio-8080-exec-2] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 200 OK 14:17:07.386 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.DispatcherServlet - GET "/menu", parameters={} 14:17:07.386 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped to com.buka.controller.ClassController#index(Clazz, ModelAndView) Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@726f97db] was not registered for synchronization because synchronization is not active 14:17:07.386 [http-nio-8080-exec-4] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@d2e8721] will not be managed by Spring ==> Preparing: select cid,cname,teacher from class ==> Parameters: <== Columns: cid, cname, teacher <== Row: 1, 1班, zhangsan <== Row: 19, 2班, lisi <== Total: 2 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@726f97db] 14:17:07.386 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.view.JstlView - View name 'menu.jsp', model {clazz=Clazz{cid=0, cname='null', teacher='null'}, org.springframework.validation.BindingResult.clazz=org.springframework.validation.BeanPropertyBindingResult: 0 errors, modelAndView=ModelAndView [view="menu.jsp"; model={classist=[Clazz{cid=1, cname='1班', teacher='zhangsan'}, Clazz{cid=19, cname='2班', teacher='lisi'}]}], org.springframework.validation.BindingResult.modelAndView=org.springframework.validation.BeanPropertyBindingResult: 0 errors, classist=[Clazz{cid=1, cname='1班', teacher='zhangsan'}, Clazz{cid=19, cname='2班', teacher='lisi'}]} 14:17:07.386 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.view.JstlView - Forwarding to [menu.jsp] 14:17:07.386 [http-nio-8080-exec-4] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 200 OK 14:17:07.540 [http-nio-8080-exec-6] DEBUG org.springframework.web.servlet.DispatcherServlet - GET "/menu", parameters={} 14:17:07.542 [http-nio-8080-exec-6] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped to com.buka.controller.ClassController#index(Clazz, ModelAndView) Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@600acfdb] was not registered for synchronization because synchronization is not active 14:17:07.542 [http-nio-8080-exec-6] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Fetching JDBC Connection from DataSource JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@d2e8721] will not be managed by Spring ==> Preparing: select cid,cname,teacher from class ==> Parameters: <== Columns: cid, cname, teacher <== Row: 1, 1班, zhangsan <== Row: 19, 2班, lisi <== Total: 2 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@600acfdb] 14:17:07.547 [http-nio-8080-exec-6] DEBUG org.springframework.web.servlet.view.JstlView - View name 'menu.jsp', model {clazz=Clazz{cid=0, cname='null', teacher='null'}, org.springframework.validation.BindingResult.clazz=org.springframework.validation.BeanPropertyBindingResult: 0 errors, modelAndView=ModelAndView [view="menu.jsp"; model={classist=[Clazz{cid=1, cname='1班', teacher='zhangsan'}, Clazz{cid=19, cname='2班', teacher='lisi'}]}], org.springframework.validation.BindingResult.modelAndView=org.springframework.validation.BeanPropertyBindingResult: 0 errors, classist=[Clazz{cid=1, cname='1班', teacher='zhangsan'}, Clazz{cid=19, cname='2班', teacher='lisi'}]} 14:17:07.549 [http-nio-8080-exec-6] DEBUG org.springframework.web.servlet.view.JstlView - Forwarding to [menu.jsp] 14:17:07.549 [http-nio-8080-exec-6] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 200 OK 15-Sep-2025 14:17:11.430 信息 [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [E:\buka resource\Tomcat 9.0\Tomcat 9.0\webapps\manager] 14:17:11.459 [http-nio-8080-exec-9] DEBUG org.springframework.web.servlet.DispatcherServlet - POST "/addStu", parameters={masked} 14:17:11.461 [http-nio-8080-exec-9] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - Mapped to com.buka.controller.StuController#addStu(Student, ModelAndView) 14:17:11.469 [http-nio-8080-exec-9] DEBUG org.springframework.web.method.HandlerMethod - Could not resolve parameter [0] in public org.springframework.web.servlet.ModelAndView com.buka.controller.StuController.addStu(com.buka.po.Student,org.springframework.web.servlet.ModelAndView): org.springframework.validation.BeanPropertyBindingResult: 1 errors Field error in object 'student' on field 'sid': rejected value [null]; codes [typeMismatch.student.sid,typeMismatch.sid,typeMismatch.int,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.sid,sid]; arguments []; default message [sid]]; default message [Failed to convert value of type 'null' to required type 'int'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [null] to type [int] for value 'null'; nested exception is java.lang.IllegalArgumentException: A null value cannot be assigned to a primitive type] 14:17:11.472 [http-nio-8080-exec-9] WARN org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolved [org.springframework.web.method.annotation.ModelAttributeMethodProcessor$1: org.springframework.validation.BeanPropertyBindingResult: 1 errors<EOL>Field error in object 'student' on field 'sid': rejected value [null]; codes [typeMismatch.student.sid,typeMismatch.sid,typeMismatch.int,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [student.sid,sid]; arguments []; default message [sid]]; default message [Failed to convert value of type 'null' to required type 'int'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [null] to type [int] for value 'null'; nested exception is java.lang.IllegalArgumentException: A null value cannot be assigned to a primitive type]] 14:17:11.472 [http-nio-8080-exec-9] DEBUG org.springframework.web.servlet.DispatcherServlet - Completed 400 BAD_REQUEST 15-Sep-2025 14:17:11.490 信息 [Catalina-utility-1] org.apache.jasper.servlet.TldScanner.scanJars 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的JAR可以缩短启动时间和JSP编译时间。 15-Sep-2025 14:17:11.492 信息 [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployDirectory Web应用程序目录[E:\buka resource\Tomcat 9.0\Tomcat 9.0\webapps\manager]的部署已在[62]毫秒内完成
09-16
--- ## ✅ 问题分析 从你的 Tomcat 启动日志和请求日志中,我们发现以下关键信息: ### ❗关键错误日志: ```log Field error in object 'student' on field 'sid': rejected value [null]; codes [typeMismatch.student.sid,typeMismatch.sid,typeMismatch.int,typeMismatch]; arguments [...]; default message [Failed to convert value of type 'null' to required type 'int'; ...] ``` --- ## ✅ 问题本质 ### ❗`Student` 类中 `sid` 是 `int` 类型(基本类型),但表单中没有提供 `sid` 字段,Spring MVC 无法将 `null` 赋值给 `int` 类型。 --- ## ✅ 代码分析 ### `Student` 类: ```java public class Student { private int sid; // ❗基本类型 int,不能为 null private String name; private String xuehao; private int cid; } ``` ### 表单页面 `addStu.jsp`: ```jsp <form action="/addStu" method="post"> 学生名:<input name="name" type="text"><br/> 学号:<input name="xuehao" type="text"><br/> 班级id:<input name="cid" type="text"><br/> <input type="submit" value="提交"> </form> ``` 表单中 **没有 `sid` 字段**,而 `sid` 是 `int` 类型,**Spring MVC 无法将空值转换为 `int` 类型**。 --- ## ✅ 解决方案 ### ✅ 方法一:将 `sid` 改为 `Integer` 类型(推荐) ```java public class Student { private Integer sid; // ✅ 改为包装类型,可以为 null private String name; private String xuehao; private Integer cid; // getter / setter } ``` 这样,当表单中没有提交 `sid` 时,Spring 会自动将其设为 `null`,而不是抛出转换错误。 --- ### ✅ 方法二:在表单中添加隐藏的 `sid` 字段(不推荐) 如果你希望由用户手动输入或由后台生成: ```jsp <input type="hidden" name="sid" value=""> ``` 但更推荐让数据库自动生成 `sid`(如使用自增主键)。 --- ### ✅ 方法三:配置 `@InitBinder` 忽略字段(可选) 如果你不想修改 `Student` 类,也可以在控制器中忽略 `sid` 字段的绑定: ```java @InitBinder public void initBinder(WebDataBinder binder) { binder.setDisallowedFields("sid"); // 忽略 sid 字段绑定 } ``` --- ## ✅ 额外建议 ### ✅ 使用 `@Valid` 验证数据(可选) 你可以在控制器方法中添加验证: ```java @RequestMapping("/addStu") public String addStu(@Valid Student student, BindingResult result) { if (result.hasErrors()) { return "addStu.jsp"; // 返回表单页面并显示错误 } stuService.addStu(student); return "redirect:/menu"; } ``` --- ## ✅ 总结 | 问题 | 原因 | 解决方案 | |------|------|----------| | `Failed to convert value of type 'null' to required type 'int'` | `Student.sid` 是 `int` 类型,不能为 `null` | 将 `int` 改为 `Integer` | | 表单提交失败 | Spring 无法绑定空值到基本类型 | 使用包装类型或忽略字段绑定 | | 数据插入失败 | 表单字段与实体类字段不匹配 | 检查字段名、类型、是否为空值 | --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值