String的一点东西

关于String类的一点东西,算是对容易疏忽的地方进行一下总结。

先看下面这个例子:
public class StringTest {

public static void main(String[] args) {
String a="a";
String b="a";
System.out.println(a==b);

System.out.println("-------");
String aa=new String("a");
System.out.println(a==aa);

System.out.println("-------");
String aaa=new String("a");
System.out.println(aa==aaa);
}
}

执行结果是:
true
-------
false
-------
false

下面对执行结果做一下解释,也算是对String的一点总结。

String经常和原生类型放在一起,因为它太常用了。但它是一个类。而它与其他类比较不同的地方在于它生成对象的方式。一种是直接用一个带引号的字符串,另一种就是通常的new。
上面的例子中a==b返回的是true,==比较的始终是对象的地址,说明a和b指向了一样的对象。
先看String a="a"。在内存的栈区有一个string pool,这条语句是在string pool中生成了一个值为"a"的字符串对象,并将其引用赋给了a。String b="a"执行时,JVM会在String pool中找是否有值为"a"的一个对象,如果有,则将其引用赋给b,如果没有则在String pool生成一个值为"a"的新对象并将其赋给b。这里由于string pool已经存在了"a",所以直接将其引用赋给了b,而不再创建新的对象。
String aa=new String("a");这条语句实际上是先在string pool中查找是否存在值为"a"的对象,如果存在,那么在内存的堆区创建了一个值为"a"的对象,并将其引用赋给aa;如果不存在,则在string pool生成一个值为"a"的新对象,然后在堆区再创建一个值为"a"的新对象,并将其赋给aa。这个例子由于在string pool已经存在了值为"a"的对象,因此不再在这里面创建对象,而直接在堆区创建一个新对象,并将其引用给aa。
a==aa仍然是比较地址。这里返回了false,原因是a指向的是位于栈区的值为"a"的对象,而aa指向的是位于堆区的值为"a"的对象。引用不同返回false。
String aaa=new String("a");像上面分析的一样,虽然在string pool存在值为"a"的对象,但是仍然在堆区创建一个新的值为"a"的对象,引用赋给了aaa。
aa==aaa,返回了false。因为aa和aaa指向的对象值都为"a",但是指向的却是位于堆区的两个不同的对象。因此返回false。

PS:关于堆区和栈区,参见[url=http://paddy-w.iteye.com/admin/blogs/958450]Java的堆和栈[/url]
<think>好的,用户之前询问了Java注解的相关内容,但用户觉得回答不够详细,内容不够多,现在需要更全面的解释。首先,我需要详细回顾Java注解的各个方面,确保覆盖所有关键点。 首先,注解的基础部分,包括定义、元注解。然后内置注解如@Override,@Deprecated,@SuppressWarnings,还有元注解如@Target、@Retention、@Documented、@Inherited、@Repeatable。这部分需要详细说明每个的作用和使用场景。 接下来是自定义注解,如何创建,语法结构,成员变量的类型限制,默认值。还要提到注解的处理方式,包括反射处理和编译时处理,比如使用APT或者注解处理器。 然后应用场景,比如框架配置(Spring,JUnit,Lombok),代码生成,静态检查,文档生成。每个场景给出具体例子,说明注解如何发挥作用。 高级特性部分,比如注解继承的问题,虽然Java本身不支持,但可以通过@Inherited元注解或在框架中模拟。类型注解(Java 8+),重复注解(Java 8+),以及如何与泛型结合使用。 最后,给出一个自定义注解的代码示例,展示定义和使用,并结合反射处理。这样用户能更直观地理解如何实际操作。 需要确保内容全面,结构清晰,分点列出,每个部分都有足够的细节。同时,检查是否有遗漏的重要概念,比如注解处理器的使用,或者新版本Java中的特性。可能用户希望了解更深入的应用,比如在Spring中的自定义注解,或者如何通过注解生成代码,这些可以作为扩展内容。 最后,按照用户的要求,在回答后提出四个相关问题,这些问题应该覆盖注解的不同方面,帮助用户进一步学习。例如,元注解的作用、自定义注解的步骤、运行时处理注解的方法,以及新版本中的特性。</think><< Java注解(Annotation)是JDK5引入的核心语言特性,其复杂性和应用场景远超表面认知。以下是深度解析: ### 一、注解体系架构 1. **元注解(Meta-annotation)** - `@Target(ElementType.TYPE)`:限定注解可应用的元素类型(类/方法/字段等) - `@Retention(RetentionPolicy.RUNTIME)`:控制注解生命周期(源码/编译时/运行时) - `@Documented`:确保注解包含在Javadoc中 - `@Inherited`:允许子类继承父类注解(仅限类级别) - `@Repeatable(Annotations.class)`(JDK8+):支持重复注解 2. **内置注解类型** - 编译指令型:`@Override`、`@SuppressWarnings("unchecked")` - 元数据标记型:`@Deprecated(since="9")` - 模块系统:`@Deprecated(forRemoval=true)`(JDK9+) ### 二、注解处理机制 1. **运行时处理** ```java Class<?> clazz = obj.getClass(); if(clazz.isAnnotationPresent(Entity.class)){ Entity entity = clazz.getAnnotation(Entity.class); System.out.println("Table name: " + entity.tableName()); } ``` 2. **编译时处理** 实现`AbstractProcessor`处理注解: ```java @SupportedAnnotationTypes("com.example.GenerateCode") public class CodeGenerator extends AbstractProcessor { @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { // 生成源代码逻辑 return true; } } ``` ### 三、高级应用模式 1. **类型注解(JDK8+)** ```java void process(@NonNull String input, @Nullable List<@Email String> emails) {...} ``` 2. **注解继承策略** ```java @Inherited @Target(ElementType.TYPE) public @interface Auditable { String auditor() default "system"; } ``` 3. **注解参数验证** ```java @Constraint(validatedBy = PhoneValidator.class) public @interface ValidPhone { String message() default "Invalid phone number"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } ``` ### 四、企业级应用案例 1. **Spring声明式事务** ```java @Transactional( isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED, rollbackFor = {SQLException.class} ) public void transferMoney() {...} ``` 2. **JUnit5参数化测试** ```java @ParameterizedTest @CsvSource({"1, John", "2, Mary"}) void testWithParameters(int id, String name) {...} ``` 3. **自定义ORM映射** ```java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Column { String name(); boolean nullable() default true; int length() default 255; } ``` ### 五、注解处理器实战 创建代码生成器: ```java @AutoService(Processor.class) public class BuilderProcessor extends AbstractProcessor { @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { for (Element element : roundEnv.getElementsWithAnnotation(Builder.class)) { // 解析类结构 // 生成Builder类 JavaFileObject builderFile = processingEnv.getFiler() .createSourceFile(element.getSimpleName() + "Builder"); try (Writer writer = builderFile.openWriter()) { writer.write(generateBuilderCode(element)); } } return true; } } ``` ### 六、性能注意事项 1. 反射获取注解的性能开销(考虑缓存Annotation实例) 2. 编译时处理与运行时处理的取舍 3. 注解参数类型的限制(只能使用基本类型、String、Class、枚举、注解或数组) ### 七、未来发展方向 1. 记录类注解(JDK16+) 2. 模式匹配增强(JDK21+) 3. 值类型注解(Valhalla项目)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值