diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java
index ffcea9d0b0c7..60a45977513e 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscoverer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -625,7 +625,7 @@ private PointcutBody getPointcutBody(String[] tokens, int startIndex) {
 			StringBuilder sb = new StringBuilder();
 			if (bodyStart >= 0 && bodyStart != (currentToken.length() - 1)) {
 				sb.append(currentToken.substring(bodyStart + 1));
-				sb.append(" ");
+				sb.append(' ');
 			}
 			numTokensConsumed++;
 			int currentIndex = startIndex + numTokensConsumed;
@@ -645,7 +645,7 @@ private PointcutBody getPointcutBody(String[] tokens, int startIndex) {
 					toAppend = toAppend.substring(1);
 				}
 				sb.append(toAppend);
-				sb.append(" ");
+				sb.append(' ');
 				currentIndex++;
 				numTokensConsumed++;
 			}
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java
index 1cdef3141da1..8b5e5f6f3e0f 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJExpressionPointcut.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -547,7 +547,7 @@ public String toString() {
 		StringBuilder sb = new StringBuilder("AspectJExpressionPointcut: (");
 		for (int i = 0; i < this.pointcutParameterTypes.length; i++) {
 			sb.append(this.pointcutParameterTypes[i].getName());
-			sb.append(" ");
+			sb.append(' ');
 			sb.append(this.pointcutParameterNames[i]);
 			if ((i+1) < this.pointcutParameterTypes.length) {
 				sb.append(", ");
diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint.java
index d25ec2eb6bc4..ef9016a15728 100644
--- a/spring-aop/src/main/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint.java
+++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -255,19 +255,19 @@ private String toString(boolean includeModifier, boolean includeReturnTypeAndArg
 			StringBuilder sb = new StringBuilder();
 			if (includeModifier) {
 				sb.append(Modifier.toString(getModifiers()));
-				sb.append(" ");
+				sb.append(' ');
 			}
 			if (includeReturnTypeAndArgs) {
 				appendType(sb, getReturnType(), useLongReturnAndArgumentTypeName);
-				sb.append(" ");
+				sb.append(' ');
 			}
 			appendType(sb, getDeclaringType(), useLongTypeName);
-			sb.append(".");
+			sb.append('.');
 			sb.append(getMethod().getName());
-			sb.append("(");
+			sb.append('(');
 			Class<?>[] parametersTypes = getParameterTypes();
 			appendTypes(sb, parametersTypes, includeReturnTypeAndArgs, useLongReturnAndArgumentTypeName);
-			sb.append(")");
+			sb.append(')');
 			return sb.toString();
 		}
 
@@ -278,7 +278,7 @@ private void appendTypes(StringBuilder sb, Class<?>[] types, boolean includeArgs
 				for (int size = types.length, i = 0; i < size; i++) {
 					appendType(sb, types[i], useLongReturnAndArgumentTypeName);
 					if (i < size - 1) {
-						sb.append(",");
+						sb.append(',');
 					}
 				}
 			}
diff --git a/spring-aop/src/main/java/org/springframework/aop/support/AbstractBeanFactoryPointcutAdvisor.java b/spring-aop/src/main/java/org/springframework/aop/support/AbstractBeanFactoryPointcutAdvisor.java
index ac69e3962b06..ccb008ebd013 100644
--- a/spring-aop/src/main/java/org/springframework/aop/support/AbstractBeanFactoryPointcutAdvisor.java
+++ b/spring-aop/src/main/java/org/springframework/aop/support/AbstractBeanFactoryPointcutAdvisor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -137,7 +137,7 @@ public String toString() {
 		StringBuilder sb = new StringBuilder(getClass().getName());
 		sb.append(": advice ");
 		if (this.adviceBeanName != null) {
-			sb.append("bean '").append(this.adviceBeanName).append("'");
+			sb.append("bean '").append(this.adviceBeanName).append('\'');
 		}
 		else {
 			sb.append(this.advice);
diff --git a/spring-aop/src/main/java/org/springframework/aop/target/AbstractBeanFactoryBasedTargetSource.java b/spring-aop/src/main/java/org/springframework/aop/target/AbstractBeanFactoryBasedTargetSource.java
index cf32c396d847..78c6d3abf6d6 100644
--- a/spring-aop/src/main/java/org/springframework/aop/target/AbstractBeanFactoryBasedTargetSource.java
+++ b/spring-aop/src/main/java/org/springframework/aop/target/AbstractBeanFactoryBasedTargetSource.java
@@ -191,9 +191,9 @@ public int hashCode() {
 	@Override
 	public String toString() {
 		StringBuilder sb = new StringBuilder(getClass().getSimpleName());
-		sb.append(" for target bean '").append(this.targetBeanName).append("'");
+		sb.append(" for target bean '").append(this.targetBeanName).append('\'');
 		if (this.targetClass != null) {
-			sb.append(" of type [").append(this.targetClass.getName()).append("]");
+			sb.append(" of type [").append(this.targetClass.getName()).append(']');
 		}
 		return sb.toString();
 	}
diff --git a/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscovererTests.java b/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscovererTests.java
index bd37f5d3770c..40a5de331039 100644
--- a/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscovererTests.java
+++ b/spring-aop/src/test/java/org/springframework/aop/aspectj/AspectJAdviceParameterNameDiscovererTests.java
@@ -276,14 +276,14 @@ protected void assertException(Method method, String pointcut, String returning,
 
 	private static String format(String[] names) {
 		StringBuilder sb = new StringBuilder();
-		sb.append("(");
+		sb.append('(');
 		for (int i = 0; i < names.length; i++) {
 			sb.append(names[i]);
 			if ((i + 1) < names.length) {
-				sb.append(",");
+				sb.append(',');
 			}
 		}
-		sb.append(")");
+		sb.append(')');
 		return sb.toString();
 	}
 
diff --git a/spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java b/spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java
index 38a59ba3d687..2c419b1c109b 100644
--- a/spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java
+++ b/spring-beans/src/main/java/org/springframework/beans/TypeConverterDelegate.java
@@ -247,14 +247,14 @@ else if (conversionService != null && typeDescriptor != null) {
 				// Definitely doesn't match: throw IllegalArgumentException/IllegalStateException
 				StringBuilder msg = new StringBuilder();
 				msg.append("Cannot convert value of type '").append(ClassUtils.getDescriptiveType(newValue));
-				msg.append("' to required type '").append(ClassUtils.getQualifiedName(requiredType)).append("'");
+				msg.append("' to required type '").append(ClassUtils.getQualifiedName(requiredType)).append('\'');
 				if (propertyName != null) {
-					msg.append(" for property '").append(propertyName).append("'");
+					msg.append(" for property '").append(propertyName).append('\'');
 				}
 				if (editor != null) {
 					msg.append(": PropertyEditor [").append(editor.getClass().getName()).append(
 							"] returned inappropriate value of type '").append(
-							ClassUtils.getDescriptiveType(convertedValue)).append("'");
+							ClassUtils.getDescriptiveType(convertedValue)).append('\'');
 					throw new IllegalArgumentException(msg.toString());
 				}
 				else {
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java
index 9978f979b506..a4cf5f314ced 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -217,13 +217,13 @@ private String buildExceptionMessage(List<String> invalidProperties, String bean
 					sb.append(" and");
 				}
 				else {
-					sb.append(",");
+					sb.append(',');
 				}
 			}
-			sb.append(" '").append(propertyName).append("'");
+			sb.append(" '").append(propertyName).append('\'');
 		}
 		sb.append(size == 1 ? " is" : " are");
-		sb.append(" required for bean '").append(beanName).append("'");
+		sb.append(" required for bean '").append(beanName).append('\'');
 		return sb.toString();
 	}
 
diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java
index 5b5471a88323..2ceff658dbce 100644
--- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java
+++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanDefinition.java
@@ -1241,7 +1241,7 @@ public int hashCode() {
 	@Override
 	public String toString() {
 		StringBuilder sb = new StringBuilder("class [");
-		sb.append(getBeanClassName()).append("]");
+		sb.append(getBeanClassName()).append(']');
 		sb.append("; scope=").append(this.scope);
 		sb.append("; abstract=").append(this.abstractFlag);
 		sb.append("; lazyInit=").append(this.lazyInit);
diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheOperation.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheOperation.java
index d1771b1bd6e3..036a4f6cb587 100644
--- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheOperation.java
+++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/AbstractJCacheOperation.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -138,7 +138,7 @@ protected ExceptionTypeFilter createExceptionTypeFilter(
 
 	@Override
 	public String toString() {
-		return getOperationDescription().append("]").toString();
+		return getOperationDescription().append(']').toString();
 	}
 
 	/**
@@ -148,7 +148,7 @@ public String toString() {
 	protected StringBuilder getOperationDescription() {
 		StringBuilder result = new StringBuilder();
 		result.append(getClass().getSimpleName());
-		result.append("[");
+		result.append('[');
 		result.append(this.methodDetails);
 		return result;
 	}
diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheEvictOperation.java b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheEvictOperation.java
index 7e72078a1d21..ee9ec6e95c67 100644
--- a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheEvictOperation.java
+++ b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheEvictOperation.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -71,9 +71,9 @@ public void setBeforeInvocation(boolean beforeInvocation) {
 		@Override
 		protected StringBuilder getOperationDescription() {
 			StringBuilder sb = super.getOperationDescription();
-			sb.append(",");
+			sb.append(',');
 			sb.append(this.cacheWide);
-			sb.append(",");
+			sb.append(',');
 			sb.append(this.beforeInvocation);
 			return sb;
 		}
diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperation.java b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperation.java
index 69f7305373f8..aaee9b396b75 100644
--- a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperation.java
+++ b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheOperation.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -216,13 +216,13 @@ public void setCondition(String condition) {
 		 */
 		protected StringBuilder getOperationDescription() {
 			StringBuilder result = new StringBuilder(getClass().getSimpleName());
-			result.append("[").append(this.name);
+			result.append('[').append(this.name);
 			result.append("] caches=").append(this.cacheNames);
 			result.append(" | key='").append(this.key);
 			result.append("' | keyGenerator='").append(this.keyGenerator);
 			result.append("' | cacheManager='").append(this.cacheManager);
 			result.append("' | cacheResolver='").append(this.cacheResolver);
-			result.append("' | condition='").append(this.condition).append("'");
+			result.append("' | condition='").append(this.condition).append('\'');
 			return result;
 		}
 
diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/CachePutOperation.java b/spring-context/src/main/java/org/springframework/cache/interceptor/CachePutOperation.java
index d5b39ee788ca..4b94ac5edff5 100644
--- a/spring-context/src/main/java/org/springframework/cache/interceptor/CachePutOperation.java
+++ b/spring-context/src/main/java/org/springframework/cache/interceptor/CachePutOperation.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -66,7 +66,7 @@ protected StringBuilder getOperationDescription() {
 			StringBuilder sb = super.getOperationDescription();
 			sb.append(" | unless='");
 			sb.append(this.unless);
-			sb.append("'");
+			sb.append('\'');
 			return sb;
 		}
 
diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheableOperation.java b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheableOperation.java
index 922407d33571..9f7fcc2e97b0 100644
--- a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheableOperation.java
+++ b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheableOperation.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -79,10 +79,10 @@ protected StringBuilder getOperationDescription() {
 			StringBuilder sb = super.getOperationDescription();
 			sb.append(" | unless='");
 			sb.append(this.unless);
-			sb.append("'");
+			sb.append('\'');
 			sb.append(" | sync='");
 			sb.append(this.sync);
-			sb.append("'");
+			sb.append('\'');
 			return sb;
 		}
 
diff --git a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java
index e78c794ca555..bc7e1f939899 100644
--- a/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java
+++ b/spring-context/src/main/java/org/springframework/context/event/ApplicationListenerMethodAdapter.java
@@ -396,7 +396,7 @@ protected String getCondition() {
 	 * @param message error message to append the HandlerMethod details to
 	 */
 	protected String getDetailedErrorMessage(Object bean, String message) {
-		StringBuilder sb = new StringBuilder(message).append("\n");
+		StringBuilder sb = new StringBuilder(message).append('\n');
 		sb.append("HandlerMethod details: \n");
 		sb.append("Bean [").append(bean.getClass().getName()).append("]\n");
 		sb.append("Method [").append(this.method.toGenericString()).append("]\n");
@@ -426,7 +426,7 @@ private String getInvocationErrorMessage(Object bean, String message, Object[] r
 		StringBuilder sb = new StringBuilder(getDetailedErrorMessage(bean, message));
 		sb.append("Resolved arguments: \n");
 		for (int i = 0; i < resolvedArgs.length; i++) {
-			sb.append("[").append(i).append("] ");
+			sb.append('[').append(i).append("] ");
 			if (resolvedArgs[i] == null) {
 				sb.append("[null] \n");
 			}
diff --git a/spring-context/src/main/java/org/springframework/context/support/LiveBeansView.java b/spring-context/src/main/java/org/springframework/context/support/LiveBeansView.java
index 668710f02bdc..96a9b212e39c 100644
--- a/spring-context/src/main/java/org/springframework/context/support/LiveBeansView.java
+++ b/spring-context/src/main/java/org/springframework/context/support/LiveBeansView.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -205,12 +205,12 @@ protected String generateJson(Set<ConfigurableApplicationContext> contexts) {
 				}
 			}
 			result.append("]\n");
-			result.append("}");
+			result.append('}');
 			if (it.hasNext()) {
 				result.append(",\n");
 			}
 		}
-		result.append("]");
+		result.append(']');
 		return result.toString();
 	}
 
diff --git a/spring-core/src/main/java/org/springframework/core/Constants.java b/spring-core/src/main/java/org/springframework/core/Constants.java
index 1515955483f1..8e91d511c10c 100644
--- a/spring-core/src/main/java/org/springframework/core/Constants.java
+++ b/spring-core/src/main/java/org/springframework/core/Constants.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -324,7 +324,7 @@ public String propertyToConstantNamePrefix(String propertyName) {
 		for (int i = 0; i < propertyName.length(); i++) {
 			char c = propertyName.charAt(i);
 			if (Character.isUpperCase(c)) {
-				parsedPrefix.append("_");
+				parsedPrefix.append('_');
 				parsedPrefix.append(c);
 			}
 			else {
diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAttributes.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAttributes.java
index 3a6f44f3ead3..d864a4cb1e1d 100644
--- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAttributes.java
+++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotationAttributes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -394,9 +394,11 @@ public String toString() {
 			sb.append(entry.getKey());
 			sb.append('=');
 			sb.append(valueToString(entry.getValue()));
-			sb.append(entries.hasNext() ? ", " : "");
+			if (entries.hasNext()) {
+				sb.append(", ");
+			}
 		}
-		sb.append("}");
+		sb.append('}');
 		return sb.toString();
 	}
 
diff --git a/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java b/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java
index 16a5e82b4b67..0201e15e2698 100644
--- a/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java
+++ b/spring-core/src/main/java/org/springframework/core/annotation/SynthesizedMergedAnnotationInvocationHandler.java
@@ -177,17 +177,17 @@ private int getValueHashCode(Object value) {
 	private String annotationToString() {
 		String string = this.string;
 		if (string == null) {
-			StringBuilder builder = new StringBuilder("@").append(this.type.getName()).append("(");
+			StringBuilder builder = new StringBuilder("@").append(this.type.getName()).append('(');
 			for (int i = 0; i < this.attributes.size(); i++) {
 				Method attribute = this.attributes.get(i);
 				if (i > 0) {
 					builder.append(", ");
 				}
 				builder.append(attribute.getName());
-				builder.append("=");
+				builder.append('=');
 				builder.append(toString(getAttributeValue(attribute)));
 			}
-			builder.append(")");
+			builder.append(')');
 			string = builder.toString();
 			this.string = string;
 		}
@@ -206,7 +206,7 @@ private String toString(Object value) {
 				}
 				builder.append(toString(Array.get(value, i)));
 			}
-			builder.append("]");
+			builder.append(']');
 			return builder.toString();
 		}
 		return String.valueOf(value);
diff --git a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java
index de43740b852a..1bc8cb281b1f 100644
--- a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java
+++ b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java
@@ -513,7 +513,7 @@ public int hashCode() {
 	public String toString() {
 		StringBuilder builder = new StringBuilder();
 		for (Annotation ann : getAnnotations()) {
-			builder.append("@").append(ann.annotationType().getName()).append(' ');
+			builder.append('@').append(ann.annotationType().getName()).append(' ');
 		}
 		builder.append(getResolvableType());
 		return builder.toString();
diff --git a/spring-core/src/main/java/org/springframework/util/StopWatch.java b/spring-core/src/main/java/org/springframework/util/StopWatch.java
index 8076ed042d17..505c27dbd107 100644
--- a/spring-core/src/main/java/org/springframework/util/StopWatch.java
+++ b/spring-core/src/main/java/org/springframework/util/StopWatch.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -302,7 +302,7 @@ public String prettyPrint() {
 			for (TaskInfo task : getTaskInfo()) {
 				sb.append(nf.format(task.getTimeNanos())).append("  ");
 				sb.append(pf.format((double) task.getTimeNanos() / getTotalTimeNanos())).append("  ");
-				sb.append(task.getTaskName()).append("\n");
+				sb.append(task.getTaskName()).append('\n');
 			}
 		}
 		return sb.toString();
@@ -320,7 +320,7 @@ public String toString() {
 			for (TaskInfo task : getTaskInfo()) {
 				sb.append("; [").append(task.getTaskName()).append("] took ").append(task.getTimeNanos()).append(" ns");
 				long percent = Math.round(100.0 * task.getTimeNanos() / getTotalTimeNanos());
-				sb.append(" = ").append(percent).append("%");
+				sb.append(" = ").append(percent).append('%');
 			}
 		}
 		else {
diff --git a/spring-core/src/test/java/org/springframework/util/FastByteArrayOutputStreamTests.java b/spring-core/src/test/java/org/springframework/util/FastByteArrayOutputStreamTests.java
index 9831d5c07f78..692d6876f159 100644
--- a/spring-core/src/test/java/org/springframework/util/FastByteArrayOutputStreamTests.java
+++ b/spring-core/src/test/java/org/springframework/util/FastByteArrayOutputStreamTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -194,7 +194,7 @@ void updateMessageDigest() throws Exception {
 		this.os.write(this.helloBytes);
 		InputStream inputStream = this.os.getInputStream();
 		DigestUtils.appendMd5DigestAsHex(inputStream, builder);
-		builder.append("\"");
+		builder.append('"');
 		String actual = builder.toString();
 		assertThat(actual).isEqualTo("\"0b10a8db164e0754105b7a99be72e3fe5\"");
 	}
@@ -208,7 +208,7 @@ void updateMessageDigestManyBuffers() throws Exception {
 		}
 		InputStream inputStream = this.os.getInputStream();
 		DigestUtils.appendMd5DigestAsHex(inputStream, builder);
-		builder.append("\"");
+		builder.append('"');
 		String actual = builder.toString();
 		assertThat(actual).isEqualTo("\"06225ca1e4533354c516e74512065331d\"");
 	}
diff --git a/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java b/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java
index 145a44275f1d..9d81c82d5f1c 100644
--- a/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java
+++ b/spring-core/src/test/java/org/springframework/util/StringUtilsTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -612,7 +612,7 @@ private void doTestCommaDelimitedListToStringArrayLegalMatch(String[] components
 		StringBuilder sb = new StringBuilder();
 		for (int i = 0; i < components.length; i++) {
 			if (i != 0) {
-				sb.append(",");
+				sb.append(',');
 			}
 			sb.append(components[i]);
 		}
diff --git a/spring-expression/src/main/java/org/springframework/expression/ExpressionException.java b/spring-expression/src/main/java/org/springframework/expression/ExpressionException.java
index 5d6f4aec9531..0d4cb1859bd9 100644
--- a/spring-expression/src/main/java/org/springframework/expression/ExpressionException.java
+++ b/spring-expression/src/main/java/org/springframework/expression/ExpressionException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -137,7 +137,7 @@ public String toDetailedString() {
 			StringBuilder output = new StringBuilder();
 			output.append("Expression [");
 			output.append(this.expressionString);
-			output.append("]");
+			output.append(']');
 			if (this.position >= 0) {
 				output.append(" @");
 				output.append(this.position);
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/CodeFlow.java b/spring-expression/src/main/java/org/springframework/expression/spel/CodeFlow.java
index cce05824aebf..393946b21629 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/CodeFlow.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/CodeFlow.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -432,11 +432,11 @@ else if (targetDescriptor == 'I') {
 	public static String createSignatureDescriptor(Method method) {
 		Class<?>[] params = method.getParameterTypes();
 		StringBuilder sb = new StringBuilder();
-		sb.append("(");
+		sb.append('(');
 		for (Class<?> param : params) {
 			sb.append(toJvmDescriptor(param));
 		}
-		sb.append(")");
+		sb.append(')');
 		sb.append(toJvmDescriptor(method.getReturnType()));
 		return sb.toString();
 	}
@@ -453,7 +453,7 @@ public static String createSignatureDescriptor(Method method) {
 	public static String createSignatureDescriptor(Constructor<?> ctor) {
 		Class<?>[] params = ctor.getParameterTypes();
 		StringBuilder sb = new StringBuilder();
-		sb.append("(");
+		sb.append('(');
 		for (Class<?> param : params) {
 			sb.append(toJvmDescriptor(param));
 		}
@@ -473,7 +473,7 @@ public static String toJvmDescriptor(Class<?> clazz) {
 		StringBuilder sb = new StringBuilder();
 		if (clazz.isArray()) {
 			while (clazz.isArray()) {
-				sb.append("[");
+				sb.append('[');
 				clazz = clazz.getComponentType();
 			}
 		}
@@ -507,9 +507,9 @@ else if (clazz == Void.TYPE) {
 			}
 		}
 		else {
-			sb.append("L");
+			sb.append('L');
 			sb.append(clazz.getName().replace('.', '/'));
-			sb.append(";");
+			sb.append(';');
 		}
 		return sb.toString();
 	}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java b/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java
index 8998cb298889..3a03cfd9a1a4 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/SpelMessage.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -284,7 +284,7 @@ public String formatMessage(Object... inserts) {
 		formattedMessage.append("EL").append(this.code);
 		switch (this.kind) {
 			case ERROR:
-				formattedMessage.append("E");
+				formattedMessage.append('E');
 				break;
 		}
 		formattedMessage.append(": ");
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/BeanReference.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/BeanReference.java
index a59d98250fbb..6e128dae6119 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/BeanReference.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/BeanReference.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -64,13 +64,13 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
 	public String toStringAST() {
 		StringBuilder sb = new StringBuilder();
 		if (!this.beanName.startsWith(FACTORY_BEAN_PREFIX)) {
-			sb.append("@");
+			sb.append('@');
 		}
 		if (!this.beanName.contains(".")) {
 			sb.append(this.beanName);
 		}
 		else {
-			sb.append("'").append(this.beanName).append("'");
+			sb.append('\'').append(this.beanName).append('\'');
 		}
 		return sb.toString();
 	}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java
index c70fcfb6da26..7ccc4c16d962 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -208,14 +208,14 @@ public String toStringAST() {
 		StringBuilder sb = new StringBuilder("new ");
 		int index = 0;
 		sb.append(getChild(index++).toStringAST());
-		sb.append("(");
+		sb.append('(');
 		for (int i = index; i < getChildCount(); i++) {
 			if (i > index) {
-				sb.append(",");
+				sb.append(',');
 			}
 			sb.append(getChild(i).toStringAST());
 		}
-		sb.append(")");
+		sb.append(')');
 		return sb.toString();
 	}
 
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineMap.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineMap.java
index b9aa0d5a8c7b..c70759b03fe1 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineMap.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/InlineMap.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -140,13 +140,13 @@ public String toStringAST() {
 		int count = getChildCount();
 		for (int c = 0; c < count; c++) {
 			if (c > 0) {
-				sb.append(",");
+				sb.append(',');
 			}
 			sb.append(getChild(c++).toStringAST());
-			sb.append(":");
+			sb.append(':');
 			sb.append(getChild(c).toStringAST());
 		}
-		sb.append("}");
+		sb.append('}');
 		return sb.toString();
 	}
 
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Operator.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Operator.java
index 12cd2836a7c6..ec31559e379f 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Operator.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Operator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -81,10 +81,10 @@ public String toStringAST() {
 		StringBuilder sb = new StringBuilder("(");
 		sb.append(getChild(0).toStringAST());
 		for (int i = 1; i < getChildCount(); i++) {
-			sb.append(" ").append(getOperatorName()).append(" ");
+			sb.append(' ').append(getOperatorName()).append(' ');
 			sb.append(getChild(i).toStringAST());
 		}
-		sb.append(")");
+		sb.append(')');
 		return sb.toString();
 	}
 
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/QualifiedIdentifier.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/QualifiedIdentifier.java
index bbf1d2d50d9b..d66a4c39ce83 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/QualifiedIdentifier.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/QualifiedIdentifier.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -49,7 +49,7 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
 			for (int i = 0; i < getChildCount(); i++) {
 				Object value = this.children[i].getValueInternal(state).getValue();
 				if (i > 0 && (value == null || !value.toString().startsWith("$"))) {
-					sb.append(".");
+					sb.append('.');
 				}
 				sb.append(value);
 			}
@@ -67,7 +67,7 @@ public String toStringAST() {
 		else {
 			for (int i = 0; i < getChildCount(); i++) {
 				if (i > 0) {
-					sb.append(".");
+					sb.append('.');
 				}
 				sb.append(getChild(i).toStringAST());
 			}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/TypeReference.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/TypeReference.java
index 8eac5d67bfe3..02e8a28c3028 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/TypeReference.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/TypeReference.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -90,7 +90,7 @@ public String toStringAST() {
 		for (int d = 0; d < this.dimensions; d++) {
 			sb.append("[]");
 		}
-		sb.append(")");
+		sb.append(')');
 		return sb.toString();
 	}
 
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/standard/Token.java b/spring-expression/src/main/java/org/springframework/expression/spel/standard/Token.java
index 21ab3e561dd2..dda0ff2152c0 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/standard/Token.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/standard/Token.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -88,12 +88,12 @@ public Token asBetweenToken() {
 	@Override
 	public String toString() {
 		StringBuilder s = new StringBuilder();
-		s.append("[").append(this.kind.toString());
+		s.append('[').append(this.kind.toString());
 		if (this.kind.hasPayload()) {
-			s.append(":").append(this.data);
+			s.append(':').append(this.data);
 		}
-		s.append("]");
-		s.append("(").append(this.startPos).append(",").append(this.endPos).append(")");
+		s.append(']');
+		s.append('(').append(this.startPos).append(',').append(this.endPos).append(')');
 		return s.toString();
 	}
 
diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/AbstractExpressionTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/AbstractExpressionTests.java
index 43ae0324961c..0e133522f621 100644
--- a/spring-expression/src/test/java/org/springframework/expression/spel/AbstractExpressionTests.java
+++ b/spring-expression/src/test/java/org/springframework/expression/spel/AbstractExpressionTests.java
@@ -245,22 +245,22 @@ protected static String stringValueOf(Object value, boolean isNested) {
 					sb.append("int[").append(l.length).append("]{");
 					for (int j = 0; j < l.length; j++) {
 						if (j > 0) {
-							sb.append(",");
+							sb.append(',');
 						}
 						sb.append(stringValueOf(l[j]));
 					}
-					sb.append("}");
+					sb.append('}');
 				}
 				else if (primitiveType == Long.TYPE) {
 					long[] l = (long[]) value;
 					sb.append("long[").append(l.length).append("]{");
 					for (int j = 0; j < l.length; j++) {
 						if (j > 0) {
-							sb.append(",");
+							sb.append(',');
 						}
 						sb.append(stringValueOf(l[j]));
 					}
-					sb.append("}");
+					sb.append('}');
 				}
 				else {
 					throw new RuntimeException("Please implement support for type " + primitiveType.getName() +
@@ -272,32 +272,32 @@ else if (value.getClass().getComponentType().isArray()) {
 				if (!isNested) {
 					sb.append(value.getClass().getComponentType().getName());
 				}
-				sb.append("[").append(l.size()).append("]{");
+				sb.append('[').append(l.size()).append("]{");
 				int i = 0;
 				for (Object object : l) {
 					if (i > 0) {
-						sb.append(",");
+						sb.append(',');
 					}
 					i++;
 					sb.append(stringValueOf(object, true));
 				}
-				sb.append("}");
+				sb.append('}');
 			}
 			else {
 				List<Object> l = Arrays.asList((Object[]) value);
 				if (!isNested) {
 					sb.append(value.getClass().getComponentType().getName());
 				}
-				sb.append("[").append(l.size()).append("]{");
+				sb.append('[').append(l.size()).append("]{");
 				int i = 0;
 				for (Object object : l) {
 					if (i > 0) {
-						sb.append(",");
+						sb.append(',');
 					}
 					i++;
 					sb.append(stringValueOf(object));
 				}
-				sb.append("}");
+				sb.append('}');
 			}
 			return sb.toString();
 		}
diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/SpelCompilationCoverageTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/SpelCompilationCoverageTests.java
index 993a6450f814..74af20b3f1ed 100644
--- a/spring-expression/src/test/java/org/springframework/expression/spel/SpelCompilationCoverageTests.java
+++ b/spring-expression/src/test/java/org/springframework/expression/spel/SpelCompilationCoverageTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -5111,21 +5111,21 @@ private String stringify(Object object) {
 			List<?> ls = (List<?>) object;
 			for (Object l: ls) {
 				s.append(l);
-				s.append(" ");
+				s.append(' ');
 			}
 		}
 		else if (object instanceof Object[]) {
 			Object[] os = (Object[]) object;
 			for (Object o: os) {
 				s.append(o);
-				s.append(" ");
+				s.append(' ');
 			}
 		}
 		else if (object instanceof int[]) {
 			int[] is = (int[]) object;
 			for (int i: is) {
 				s.append(i);
-				s.append(" ");
+				s.append(' ');
 			}
 		}
 		else {
@@ -5931,9 +5931,9 @@ public Obj3(int... params) {
 		public Obj3(String s, Float f, int... ints) {
 			StringBuilder b = new StringBuilder();
 			b.append(s);
-			b.append(":");
+			b.append(':');
 			b.append(Float.toString(f));
-			b.append(":");
+			b.append(':');
 			for (int param: ints) {
 				b.append(Integer.toString(param));
 			}
diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java
index 2997f8745557..2f6105cafcf7 100755
--- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java
+++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -646,13 +646,13 @@ public String createCallString() {
 		}
 
 		if (StringUtils.hasLength(catalogNameToUse)) {
-			callString.append(catalogNameToUse).append(".");
+			callString.append(catalogNameToUse).append('.');
 		}
 		if (StringUtils.hasLength(schemaNameToUse)) {
-			callString.append(schemaNameToUse).append(".");
+			callString.append(schemaNameToUse).append('.');
 		}
 		callString.append(this.metaDataProvider.procedureNameToUse(getProcedureName()));
-		callString.append("(");
+		callString.append('(');
 
 		for (SqlParameter parameter : this.callParameters) {
 			if (!parameter.isResultsParameter()) {
diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java
index 13e582a113d1..be0ef871bc40 100644
--- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java
+++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/TableMetaDataContext.java
@@ -280,7 +280,7 @@ public String createInsertString(String... generatedKeyNames) {
 		insertStatement.append("INSERT INTO ");
 		if (getSchemaName() != null) {
 			insertStatement.append(getSchemaName());
-			insertStatement.append(".");
+			insertStatement.append('.');
 		}
 		insertStatement.append(getTableName());
 		insertStatement.append(" (");
@@ -313,7 +313,7 @@ public String createInsertString(String... generatedKeyNames) {
 		}
 		String params = String.join(", ", Collections.nCopies(columnCount, "?"));
 		insertStatement.append(params);
-		insertStatement.append(")");
+		insertStatement.append(')');
 		return insertStatement.toString();
 	}
 
diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.java
index f1afd5604c0a..aed3ddb54b4c 100644
--- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.java
+++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -186,10 +186,10 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
 					// Allow for differentiating between the proxy and the raw Connection.
 					StringBuilder sb = new StringBuilder("Transaction-aware proxy for target Connection ");
 					if (this.target != null) {
-						sb.append("[").append(this.target.toString()).append("]");
+						sb.append('[').append(this.target.toString()).append(']');
 					}
 					else {
-						sb.append(" from DataSource [").append(this.targetDataSource).append("]");
+						sb.append(" from DataSource [").append(this.targetDataSource).append(']');
 					}
 					return sb.toString();
 				case "close":
diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/AbstractIdentityColumnMaxValueIncrementer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/AbstractIdentityColumnMaxValueIncrementer.java
index 0bb444515724..5c523a128c32 100644
--- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/AbstractIdentityColumnMaxValueIncrementer.java
+++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/incrementer/AbstractIdentityColumnMaxValueIncrementer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -152,7 +152,7 @@ protected String getDeleteStatement(long[] values) {
 			for (int i = 0; i < values.length - 1; i++) {
 				sb.append(", ").append(values[i]);
 			}
-			sb.append(")");
+			sb.append(')');
 		}
 		else {
 			long maxValue = values[values.length - 1];
diff --git a/spring-jms/src/main/java/org/springframework/jms/config/AbstractJmsListenerEndpoint.java b/spring-jms/src/main/java/org/springframework/jms/config/AbstractJmsListenerEndpoint.java
index 242e7344a8d5..2e0fb1a9b4bc 100644
--- a/spring-jms/src/main/java/org/springframework/jms/config/AbstractJmsListenerEndpoint.java
+++ b/spring-jms/src/main/java/org/springframework/jms/config/AbstractJmsListenerEndpoint.java
@@ -177,9 +177,9 @@ private void setupMessageListener(MessageListenerContainer container) {
 	 */
 	protected StringBuilder getEndpointDescription() {
 		StringBuilder result = new StringBuilder();
-		return result.append(getClass().getSimpleName()).append("[").append(this.id).append("] destination=").
+		return result.append(getClass().getSimpleName()).append('[').append(this.id).append("] destination=").
 				append(this.destination).append("' | subscription='").append(this.subscription).
-				append(" | selector='").append(this.selector).append("'");
+				append(" | selector='").append(this.selector).append('\'');
 	}
 
 	@Override
diff --git a/spring-jms/src/main/java/org/springframework/jms/config/MethodJmsListenerEndpoint.java b/spring-jms/src/main/java/org/springframework/jms/config/MethodJmsListenerEndpoint.java
index 4ea38a377839..f1548090c290 100644
--- a/spring-jms/src/main/java/org/springframework/jms/config/MethodJmsListenerEndpoint.java
+++ b/spring-jms/src/main/java/org/springframework/jms/config/MethodJmsListenerEndpoint.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -224,8 +224,8 @@ private String resolve(String value) {
 	@Override
 	protected StringBuilder getEndpointDescription() {
 		return super.getEndpointDescription()
-				.append(" | bean='").append(this.bean).append("'")
-				.append(" | method='").append(this.method).append("'");
+				.append(" | bean='").append(this.bean).append('\'')
+				.append(" | method='").append(this.method).append('\'');
 	}
 
 }
diff --git a/spring-jms/src/main/java/org/springframework/jms/config/SimpleJmsListenerEndpoint.java b/spring-jms/src/main/java/org/springframework/jms/config/SimpleJmsListenerEndpoint.java
index ac1808cd40ce..33be14be058d 100644
--- a/spring-jms/src/main/java/org/springframework/jms/config/SimpleJmsListenerEndpoint.java
+++ b/spring-jms/src/main/java/org/springframework/jms/config/SimpleJmsListenerEndpoint.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -63,7 +63,7 @@ protected MessageListener createMessageListener(MessageListenerContainer contain
 	@Override
 	protected StringBuilder getEndpointDescription() {
 		return super.getEndpointDescription()
-				.append(" | messageListener='").append(this.messageListener).append("'");
+				.append(" | messageListener='").append(this.messageListener).append('\'');
 	}
 
 }
diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapter.java b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapter.java
index daec6b656b27..91072e40cb5e 100644
--- a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapter.java
+++ b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -125,7 +125,7 @@ private Object invokeHandler(javax.jms.Message jmsMessage, @Nullable Session ses
 
 	private String createMessagingErrorMessage(String description) {
 		InvocableHandlerMethod handlerMethod = getHandlerMethod();
-		StringBuilder sb = new StringBuilder(description).append("\n")
+		StringBuilder sb = new StringBuilder(description).append('\n')
 				.append("Endpoint handler details:\n")
 				.append("Method [").append(handlerMethod.getMethod()).append("]\n")
 				.append("Bean [").append(handlerMethod.getBean()).append("]\n");
diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MethodArgumentNotValidException.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MethodArgumentNotValidException.java
index fcf668b34bc1..9ab9da75ed6f 100644
--- a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MethodArgumentNotValidException.java
+++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MethodArgumentNotValidException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -70,7 +70,7 @@ private static String getValidationErrorMessage(BindingResult bindingResult) {
 		StringBuilder sb = new StringBuilder();
 		sb.append(bindingResult.getErrorCount()).append(" error(s): ");
 		for (ObjectError error : bindingResult.getAllErrors()) {
-			sb.append("[").append(error).append("] ");
+			sb.append('[').append(error).append("] ");
 		}
 		return sb.toString();
 	}
diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/SimpMessageHeaderAccessor.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/SimpMessageHeaderAccessor.java
index 6c314f332903..307b1071e57f 100644
--- a/spring-messaging/src/main/java/org/springframework/messaging/simp/SimpMessageHeaderAccessor.java
+++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/SimpMessageHeaderAccessor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -208,7 +208,7 @@ public String getShortLogMessage(Object payload) {
 		}
 		StringBuilder sb = getBaseLogMessage();
 		if (!CollectionUtils.isEmpty(getSessionAttributes())) {
-			sb.append(" attributes[").append(getSessionAttributes().size()).append("]");
+			sb.append(" attributes[").append(getSessionAttributes().size()).append(']');
 		}
 		sb.append(getShortPayloadLogMessage(payload));
 		return sb.toString();
diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompHeaderAccessor.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompHeaderAccessor.java
index 2c25a2114e0e..7f879500cd44 100644
--- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompHeaderAccessor.java
+++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompHeaderAccessor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -452,7 +452,7 @@ public String getDetailedLogMessage(@Nullable Object payload) {
 			return super.getDetailedLogMessage(payload);
 		}
 		StringBuilder sb = new StringBuilder();
-		sb.append(command.name()).append(" ");
+		sb.append(command.name()).append(' ');
 		Map<String, List<String>> nativeHeaders = getNativeHeaders();
 		if (nativeHeaders != null) {
 			sb.append(nativeHeaders);
diff --git a/spring-messaging/src/main/java/org/springframework/messaging/support/GenericMessage.java b/spring-messaging/src/main/java/org/springframework/messaging/support/GenericMessage.java
index 0191e649f8b9..62053d5edf61 100644
--- a/spring-messaging/src/main/java/org/springframework/messaging/support/GenericMessage.java
+++ b/spring-messaging/src/main/java/org/springframework/messaging/support/GenericMessage.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -112,12 +112,12 @@ public String toString() {
 		StringBuilder sb = new StringBuilder(getClass().getSimpleName());
 		sb.append(" [payload=");
 		if (this.payload instanceof byte[]) {
-			sb.append("byte[").append(((byte[]) this.payload).length).append("]");
+			sb.append("byte[").append(((byte[]) this.payload).length).append(']');
 		}
 		else {
 			sb.append(this.payload);
 		}
-		sb.append(", headers=").append(this.headers).append("]");
+		sb.append(", headers=").append(this.headers).append(']');
 		return sb.toString();
 	}
 
diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompHeaderAccessorTests.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompHeaderAccessorTests.java
index 340a27b69310..49915dbd01f1 100644
--- a/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompHeaderAccessorTests.java
+++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/stomp/StompHeaderAccessorTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -241,7 +241,7 @@ public void getShortLogMessage() {
 
 		StringBuilder sb = new StringBuilder();
 		for (int i = 0; i < 80; i++) {
-			sb.append("a");
+			sb.append('a');
 		}
 		final String payload = sb.toString() + " > 80";
 		actual = accessor.getShortLogMessage(payload.getBytes(StandardCharsets.UTF_8));
diff --git a/spring-messaging/src/test/java/org/springframework/messaging/support/MessageHeaderAccessorTests.java b/spring-messaging/src/test/java/org/springframework/messaging/support/MessageHeaderAccessorTests.java
index ff7c4cee82e2..d87a410b028b 100644
--- a/spring-messaging/src/test/java/org/springframework/messaging/support/MessageHeaderAccessorTests.java
+++ b/spring-messaging/src/test/java/org/springframework/messaging/support/MessageHeaderAccessorTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -320,7 +320,7 @@ public String toString() {
 
 		StringBuilder sb = new StringBuilder();
 		for (int i = 0; i < 80; i++) {
-			sb.append("a");
+			sb.append('a');
 		}
 		final String payload = sb.toString() + " > 80";
 
@@ -356,7 +356,7 @@ public String toString() {
 
 		StringBuilder sb = new StringBuilder();
 		for (int i = 0; i < 80; i++) {
-			sb.append("a");
+			sb.append('a');
 		}
 		final String payload = sb.toString() + " > 80";
 
diff --git a/spring-test/src/main/java/org/springframework/mock/http/client/MockClientHttpRequest.java b/spring-test/src/main/java/org/springframework/mock/http/client/MockClientHttpRequest.java
index fa7ded971ad6..7630ac3a3b2b 100644
--- a/spring-test/src/main/java/org/springframework/mock/http/client/MockClientHttpRequest.java
+++ b/spring-test/src/main/java/org/springframework/mock/http/client/MockClientHttpRequest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -126,7 +126,7 @@ protected ClientHttpResponse executeInternal() throws IOException {
 	public String toString() {
 		StringBuilder sb = new StringBuilder();
 		sb.append(this.httpMethod);
-		sb.append(" ").append(this.uri);
+		sb.append(' ').append(this.uri);
 		if (!getHeaders().isEmpty()) {
 			sb.append(", headers: ").append(getHeaders());
 		}
diff --git a/spring-test/src/main/java/org/springframework/test/web/client/AbstractRequestExpectationManager.java b/spring-test/src/main/java/org/springframework/test/web/client/AbstractRequestExpectationManager.java
index 06de5d3ae749..10e1f39b3a55 100644
--- a/spring-test/src/main/java/org/springframework/test/web/client/AbstractRequestExpectationManager.java
+++ b/spring-test/src/main/java/org/springframework/test/web/client/AbstractRequestExpectationManager.java
@@ -193,7 +193,7 @@ protected String getRequestDetails() {
 		if (!this.requests.isEmpty()) {
 			sb.append(":\n");
 			for (ClientHttpRequest request : this.requests) {
-				sb.append(request.toString()).append("\n");
+				sb.append(request.toString()).append('\n');
 			}
 		}
 		else {
diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/DefaultTransactionAttribute.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/DefaultTransactionAttribute.java
index cdf73d003485..1c488ee06761 100644
--- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/DefaultTransactionAttribute.java
+++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/DefaultTransactionAttribute.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -231,7 +231,7 @@ public void resolveAttributeStrings(@Nullable StringValueResolver resolver) {
 	protected final StringBuilder getAttributeDescription() {
 		StringBuilder result = getDefinitionDescription();
 		if (StringUtils.hasText(this.qualifier)) {
-			result.append("; '").append(this.qualifier).append("'");
+			result.append("; '").append(this.qualifier).append('\'');
 		}
 		if (!this.labels.isEmpty()) {
 			result.append("; ").append(this.labels);
diff --git a/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageReader.java b/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageReader.java
index 849d0879cc48..035d8b4c73e9 100644
--- a/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageReader.java
+++ b/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageReader.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -147,7 +147,7 @@ private Object buildEvent(List<String> lines, ResolvableType valueType, boolean
 		for (String line : lines) {
 			if (line.startsWith("data:")) {
 				data = (data != null ? data : new StringBuilder());
-				data.append(line.substring(5).trim()).append("\n");
+				data.append(line.substring(5).trim()).append('\n');
 			}
 			if (shouldWrap) {
 				if (line.startsWith("id:")) {
@@ -161,7 +161,7 @@ else if (line.startsWith("retry:")) {
 				}
 				else if (line.startsWith(":")) {
 					comment = (comment != null ? comment : new StringBuilder());
-					comment.append(line.substring(1).trim()).append("\n");
+					comment.append(line.substring(1).trim()).append('\n');
 				}
 			}
 		}
diff --git a/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageWriter.java b/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageWriter.java
index 73befefb65b4..c3f65a31f86c 100644
--- a/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageWriter.java
+++ b/spring-web/src/main/java/org/springframework/http/codec/ServerSentEventHttpMessageWriter.java
@@ -141,7 +141,7 @@ private Flux<Publisher<DataBuffer>> encode(Publisher<?> input, ResolvableType el
 				writeField("retry", retry.toMillis(), sb);
 			}
 			if (comment != null) {
-				sb.append(':').append(StringUtils.replace(comment, "\n", "\n:")).append("\n");
+				sb.append(':').append(StringUtils.replace(comment, "\n", "\n:")).append('\n');
 			}
 			if (data != null) {
 				sb.append("data:");
@@ -181,7 +181,7 @@ private <T> Flux<DataBuffer> encodeEvent(StringBuilder eventContent, T data, Res
 	}
 
 	private void writeField(String fieldName, Object fieldValue, StringBuilder sb) {
-		sb.append(fieldName).append(':').append(fieldValue).append("\n");
+		sb.append(fieldName).append(':').append(fieldValue).append('\n');
 	}
 
 	private DataBuffer encodeText(CharSequence text, MediaType mediaType, DataBufferFactory bufferFactory) {
diff --git a/spring-web/src/main/java/org/springframework/web/bind/MethodArgumentNotValidException.java b/spring-web/src/main/java/org/springframework/web/bind/MethodArgumentNotValidException.java
index 38dab43cc57f..e51f136e4755 100644
--- a/spring-web/src/main/java/org/springframework/web/bind/MethodArgumentNotValidException.java
+++ b/spring-web/src/main/java/org/springframework/web/bind/MethodArgumentNotValidException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -64,7 +64,7 @@ public String getMessage() {
 		}
 		sb.append(": ");
 		for (ObjectError error : bindingResult.getAllErrors()) {
-			sb.append("[").append(error).append("] ");
+			sb.append('[').append(error).append("] ");
 		}
 		return sb.toString();
 	}
diff --git a/spring-web/src/main/java/org/springframework/web/bind/UnsatisfiedServletRequestParameterException.java b/spring-web/src/main/java/org/springframework/web/bind/UnsatisfiedServletRequestParameterException.java
index 5418a06accdf..65002541148b 100644
--- a/spring-web/src/main/java/org/springframework/web/bind/UnsatisfiedServletRequestParameterException.java
+++ b/spring-web/src/main/java/org/springframework/web/bind/UnsatisfiedServletRequestParameterException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -77,9 +77,9 @@ public String getMessage() {
 			if (i > 0) {
 				sb.append(" OR ");
 			}
-			sb.append("\"");
+			sb.append('"');
 			sb.append(StringUtils.arrayToDelimitedString(conditions, ", "));
-			sb.append("\"");
+			sb.append('"');
 			i++;
 		}
 		sb.append(" not met for actual request parameters: ");
diff --git a/spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeBindException.java b/spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeBindException.java
index ff8d88c7ea4a..8c605fc66254 100644
--- a/spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeBindException.java
+++ b/spring-web/src/main/java/org/springframework/web/bind/support/WebExchangeBindException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -289,7 +289,7 @@ public String getMessage() {
 				.append(parameter.getExecutable().toGenericString())
 				.append(", with ").append(this.bindingResult.getErrorCount()).append(" error(s): ");
 		for (ObjectError error : this.bindingResult.getAllErrors()) {
-			sb.append("[").append(error).append("] ");
+			sb.append('[').append(error).append("] ");
 		}
 		return sb.toString();
 	}
diff --git a/spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java b/spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java
index 88f849333aca..271193cc6382 100644
--- a/spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java
+++ b/spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -322,7 +322,7 @@ private String getAfterMessage(HttpServletRequest request) {
 	protected String createMessage(HttpServletRequest request, String prefix, String suffix) {
 		StringBuilder msg = new StringBuilder();
 		msg.append(prefix);
-		msg.append(request.getMethod()).append(" ");
+		msg.append(request.getMethod()).append(' ');
 		msg.append(request.getRequestURI());
 
 		if (isIncludeQueryString()) {
diff --git a/spring-web/src/main/java/org/springframework/web/method/support/ModelAndViewContainer.java b/spring-web/src/main/java/org/springframework/web/method/support/ModelAndViewContainer.java
index 44b6be8b54ac..5cb8d9f71ad3 100644
--- a/spring-web/src/main/java/org/springframework/web/method/support/ModelAndViewContainer.java
+++ b/spring-web/src/main/java/org/springframework/web/method/support/ModelAndViewContainer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -333,7 +333,7 @@ public String toString() {
 		StringBuilder sb = new StringBuilder("ModelAndViewContainer: ");
 		if (!isRequestHandled()) {
 			if (isViewReference()) {
-				sb.append("reference to view with name '").append(this.view).append("'");
+				sb.append("reference to view with name '").append(this.view).append('\'');
 			}
 			else {
 				sb.append("View is [").append(this.view).append(']');
diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/CaptureVariablePathElement.java b/spring-web/src/main/java/org/springframework/web/util/pattern/CaptureVariablePathElement.java
index c99d7f842241..0e7b812323c9 100644
--- a/spring-web/src/main/java/org/springframework/web/util/pattern/CaptureVariablePathElement.java
+++ b/spring-web/src/main/java/org/springframework/web/util/pattern/CaptureVariablePathElement.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -159,12 +159,12 @@ public String toString() {
 	@Override
 	public char[] getChars() {
 		StringBuilder b = new StringBuilder();
-		b.append("{");
+		b.append('{');
 		b.append(this.variableName);
 		if (this.constraintPattern != null) {
-			b.append(":").append(this.constraintPattern.pattern());
+			b.append(':').append(this.constraintPattern.pattern());
 		}
-		b.append("}");
+		b.append('}');
 		return b.toString().toCharArray();
 	}
 
diff --git a/spring-web/src/test/java/org/springframework/http/HttpRangeTests.java b/spring-web/src/test/java/org/springframework/http/HttpRangeTests.java
index 2a22b87d80cc..550b85fd36d6 100644
--- a/spring-web/src/test/java/org/springframework/http/HttpRangeTests.java
+++ b/spring-web/src/test/java/org/springframework/http/HttpRangeTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -111,7 +111,7 @@ public void parseRangesValidations() {
 		// 1. At limit..
 		StringBuilder atLimit = new StringBuilder("bytes=0-0");
 		for (int i=0; i < 99; i++) {
-			atLimit.append(",").append(i).append("-").append(i + 1);
+			atLimit.append(',').append(i).append('-').append(i + 1);
 		}
 		List<HttpRange> ranges = HttpRange.parseRanges(atLimit.toString());
 		assertThat(ranges.size()).isEqualTo(100);
@@ -119,7 +119,7 @@ public void parseRangesValidations() {
 		// 2. Above limit..
 		StringBuilder aboveLimit = new StringBuilder("bytes=0-0");
 		for (int i=0; i < 100; i++) {
-			aboveLimit.append(",").append(i).append("-").append(i + 1);
+			aboveLimit.append(',').append(i).append('-').append(i + 1);
 		}
 		assertThatIllegalArgumentException().isThrownBy(() ->
 				HttpRange.parseRanges(aboveLimit.toString()));
diff --git a/spring-web/src/test/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequestTests.java b/spring-web/src/test/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequestTests.java
index b241108a123f..62abdfdbea2c 100644
--- a/spring-web/src/test/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequestTests.java
+++ b/spring-web/src/test/java/org/springframework/web/multipart/support/DefaultMultipartHttpServletRequestTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.springframework.web.multipart.support;
 
 import java.util.HashMap;
@@ -80,7 +81,7 @@ private void insertQueryParams() {
 		for (String key : this.queryParams.keySet()) {
 			for (String value : this.queryParams.get(key)) {
 				this.servletRequest.addParameter(key, value);
-				query.append(query.length() > 0 ? "&" : "").append(key).append("=").append(value);
+				query.append(query.length() > 0 ? "&" : "").append(key).append('=').append(value);
 			}
 		}
 		this.servletRequest.setQueryString(query.toString());
diff --git a/spring-web/src/test/java/org/springframework/web/util/JavaScriptUtilsTests.java b/spring-web/src/test/java/org/springframework/web/util/JavaScriptUtilsTests.java
index 4d2e9614e6da..6fb380337ded 100644
--- a/spring-web/src/test/java/org/springframework/web/util/JavaScriptUtilsTests.java
+++ b/spring-web/src/test/java/org/springframework/web/util/JavaScriptUtilsTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2019 the original author or authors.
+ * Copyright 2004-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -33,15 +33,15 @@ public class JavaScriptUtilsTests {
 	public void escape() {
 		StringBuilder sb = new StringBuilder();
 		sb.append('"');
-		sb.append("'");
-		sb.append("\\");
-		sb.append("/");
-		sb.append("\t");
-		sb.append("\n");
-		sb.append("\r");
-		sb.append("\f");
-		sb.append("\b");
-		sb.append("\013");
+		sb.append('\'');
+		sb.append('\\');
+		sb.append('/');
+		sb.append('\t');
+		sb.append('\n');
+		sb.append('\r');
+		sb.append('\f');
+		sb.append('\b');
+		sb.append('\013');
 		assertThat(JavaScriptUtils.javaScriptEscape(sb.toString())).isEqualTo("\\\"\\'\\\\\\/\\t\\n\\n\\f\\b\\v");
 	}
 
diff --git a/spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternTests.java b/spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternTests.java
index 707809b07d63..0587fc4a8bac 100644
--- a/spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternTests.java
+++ b/spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -1210,7 +1210,7 @@ private PathPattern.PathMatchInfo matchAndExtract(PathPattern p, String path) {
 	private String elementsToString(List<Element> elements) {
 		StringBuilder s = new StringBuilder();
 		for (Element element: elements) {
-			s.append("[").append(element.value()).append("]");
+			s.append('[').append(element.value()).append(']');
 		}
 		return s.toString();
 	}
diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfo.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfo.java
index 736e46ce60d8..8782b9a5b831 100644
--- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfo.java
+++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfo.java
@@ -380,7 +380,7 @@ public String toString() {
 		}
 		if (!this.patternsCondition.isEmpty()) {
 			Set<PathPattern> patterns = this.patternsCondition.getPatterns();
-			builder.append(" ").append(patterns.size() == 1 ? patterns.iterator().next() : patterns);
+			builder.append(' ').append(patterns.size() == 1 ? patterns.iterator().next() : patterns);
 		}
 		if (!this.paramsCondition.isEmpty()) {
 			builder.append(", params ").append(this.paramsCondition);
diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/BindStatus.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/BindStatus.java
index 2a9c7432ec49..4d9b75518d8d 100644
--- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/BindStatus.java
+++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/BindStatus.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -353,7 +353,7 @@ public PropertyEditor findEditor(Class<?> valueClass) {
 	public String toString() {
 		StringBuilder sb = new StringBuilder("BindStatus: ");
 		sb.append("expression=[").append(this.expression).append("]; ");
-		sb.append("value=[").append(this.value).append("]");
+		sb.append("value=[").append(this.value).append(']');
 		if (!ObjectUtils.isEmpty(this.errorCodes)) {
 			sb.append("; errorCodes=").append(Arrays.asList(this.errorCodes));
 		}
diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/FlushingIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/FlushingIntegrationTests.java
index 66143e4f2f76..6663fa62196a 100644
--- a/spring-webflux/src/test/java/org/springframework/web/reactive/FlushingIntegrationTests.java
+++ b/spring-webflux/src/test/java/org/springframework/web/reactive/FlushingIntegrationTests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -154,7 +154,7 @@ private Flux<String> chunks1K() {
 					for (char c : "0123456789".toCharArray()) {
 						sb.append(c);
 						if (sb.length() + 1 == 1024) {
-							sink.next(sb.append("\n").toString());
+							sink.next(sb.append('\n').toString());
 							return;
 						}
 					}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java
index 9633b97d3060..a0dadcd798a1 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java
@@ -509,7 +509,7 @@ public String toString() {
 		}
 
 		// Patterns conditions are never empty and have "" (empty path) at least.
-		builder.append(" ").append(getActivePatternsCondition());
+		builder.append(' ').append(getActivePatternsCondition());
 
 		if (!this.paramsCondition.isEmpty()) {
 			builder.append(", params ").append(this.paramsCondition);
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java
index d8daa6c610e4..b1358bc47e10 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@
  *
  * @author Rossen Stoyanchev
  * @author Juergen Hoeller
+ * @author Sam Brannen
  * @since 4.2
  */
 public class SseEmitter extends ResponseBodyEmitter {
@@ -175,7 +176,7 @@ public interface SseEventBuilder {
 		SseEventBuilder data(Object object, @Nullable MediaType mediaType);
 
 		/**
-		 * Return one or more Object-MediaType  pairs to write via
+		 * Return one or more Object-MediaType pairs to write via
 		 * {@link #send(Object, MediaType)}.
 		 * @since 4.2.3
 		 */
@@ -195,25 +196,25 @@ private static class SseEventBuilderImpl implements SseEventBuilder {
 
 		@Override
 		public SseEventBuilder id(String id) {
-			append("id:").append(id).append("\n");
+			append("id:").append(id).append('\n');
 			return this;
 		}
 
 		@Override
 		public SseEventBuilder name(String name) {
-			append("event:").append(name).append("\n");
+			append("event:").append(name).append('\n');
 			return this;
 		}
 
 		@Override
 		public SseEventBuilder reconnectTime(long reconnectTimeMillis) {
-			append("retry:").append(String.valueOf(reconnectTimeMillis)).append("\n");
+			append("retry:").append(String.valueOf(reconnectTimeMillis)).append('\n');
 			return this;
 		}
 
 		@Override
 		public SseEventBuilder comment(String comment) {
-			append(":").append(comment).append("\n");
+			append(':').append(comment).append('\n');
 			return this;
 		}
 
@@ -227,7 +228,7 @@ public SseEventBuilder data(Object object, @Nullable MediaType mediaType) {
 			append("data:");
 			saveAppendedText();
 			this.dataToSend.add(new DataWithMediaType(object, mediaType));
-			append("\n");
+			append('\n');
 			return this;
 		}
 
@@ -239,12 +240,20 @@ SseEventBuilderImpl append(String text) {
 			return this;
 		}
 
+		SseEventBuilderImpl append(char ch) {
+			if (this.sb == null) {
+				this.sb = new StringBuilder();
+			}
+			this.sb.append(ch);
+			return this;
+		}
+
 		@Override
 		public Set<DataWithMediaType> build() {
 			if (!StringUtils.hasLength(this.sb) && this.dataToSend.isEmpty()) {
 				return Collections.emptySet();
 			}
-			append("\n");
+			append('\n');
 			saveAppendedText();
 			return this.dataToSend;
 		}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java
index c6b364992741..2b97ac60895f 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/PathResourceResolver.java
@@ -268,7 +268,7 @@ else if (shouldEncodeRelativePath(location) && request != null) {
 			while (tokenizer.hasMoreTokens()) {
 				String value = UriUtils.encode(tokenizer.nextToken(), charset);
 				sb.append(value);
-				sb.append("/");
+				sb.append('/');
 			}
 			if (!path.endsWith("/")) {
 				sb.setLength(sb.length() - 1);
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/BindStatus.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/BindStatus.java
index 7da8e8e7aa8f..f8debe853cdf 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/BindStatus.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/BindStatus.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2018 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -352,7 +352,7 @@ public PropertyEditor findEditor(Class<?> valueClass) {
 	public String toString() {
 		StringBuilder sb = new StringBuilder("BindStatus: ");
 		sb.append("expression=[").append(this.expression).append("]; ");
-		sb.append("value=[").append(this.value).append("]");
+		sb.append("value=[").append(this.value).append(']');
 		if (!ObjectUtils.isEmpty(this.errorCodes)) {
 			sb.append("; errorCodes=").append(Arrays.asList(this.errorCodes));
 		}
diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/UrlTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/UrlTag.java
index 08c64a259014..079b3214846f 100644
--- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/UrlTag.java
+++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/UrlTag.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -286,7 +286,7 @@ String createUrl() throws JspException {
 			}
 		}
 		if (this.type != UrlType.RELATIVE && this.type != UrlType.ABSOLUTE && !this.value.startsWith("/")) {
-			url.append("/");
+			url.append('/');
 		}
 		url.append(replaceUriTemplateParams(this.value, this.params, this.templateParams));
 		url.append(createQueryString(this.params, this.templateParams, (url.indexOf("?") == -1)));
@@ -324,15 +324,15 @@ protected String createQueryString(List<Param> params, Set<String> usedParams, b
 		for (Param param : params) {
 			if (!usedParams.contains(param.getName()) && StringUtils.hasLength(param.getName())) {
 				if (includeQueryStringDelimiter && qs.length() == 0) {
-					qs.append("?");
+					qs.append('?');
 				}
 				else {
-					qs.append("&");
+					qs.append('&');
 				}
 				try {
 					qs.append(UriUtils.encodeQueryParam(param.getName(), encoding));
 					if (param.getValue() != null) {
-						qs.append("=");
+						qs.append('=');
 						qs.append(UriUtils.encodeQueryParam(param.getValue(), encoding));
 					}
 				}
diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/HtmlFileTransportHandler.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/HtmlFileTransportHandler.java
index d39f51bbf9db..13b09e2cb1c0 100644
--- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/HtmlFileTransportHandler.java
+++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/HtmlFileTransportHandler.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -75,7 +75,7 @@ public class HtmlFileTransportHandler extends AbstractHttpSendingTransportHandle
 				);
 
 		while (sb.length() < MINIMUM_PARTIAL_HTML_CONTENT_LENGTH) {
-			sb.append(" ");
+			sb.append(' ');
 		}
 		PARTIAL_HTML_CONTENT = sb.toString();
 	}
diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompTextMessageBuilder.java b/spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompTextMessageBuilder.java
index 855b1e597227..8232ef844db3 100644
--- a/spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompTextMessageBuilder.java
+++ b/spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompTextMessageBuilder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2021 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -56,15 +56,15 @@ public StompTextMessageBuilder body(String body) {
 	}
 
 	public TextMessage build() {
-		StringBuilder sb = new StringBuilder(this.command.name()).append("\n");
+		StringBuilder sb = new StringBuilder(this.command.name()).append('\n');
 		for (String line : this.headerLines) {
-			sb.append(line).append("\n");
+			sb.append(line).append('\n');
 		}
-		sb.append("\n");
+		sb.append('\n');
 		if (this.body != null) {
 			sb.append(this.body);
 		}
-		sb.append("\u0000");
+		sb.append('\u0000');
 		return new TextMessage(sb.toString());
 	}