`
BBLLMYD
  • 浏览: 17861 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java中注解&泛型

阅读更多

1.注解(Annotation):

 

注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,如果没加则没有标记,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无标记,有什么标记,就去干相应的事.标记可以加在包,类,字段,方法,方法的参数以及局部变量上,看java.lang包,可看到JDK中提供的最基本的annotation.

 

三种基本注解:

@SuppressWarnings("deprecation")

@Deprecated

@Override 

public class AnnotationTest {

	@SuppressWarnings("deprecation")
	/*
	 * @SuppressWarnings("deprecation")//指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中会
	 * 取消编译器在编译时对方法过时发出的警告(SuppressWarning:抑制警告),即使main方法中用到过时方法也不会发出警告
	 */
	public static void main(String[] args) {
		System.runFinalizersOnExit(true);
		DeprecatedTest.say();
	}

}

class DeprecatedTest {
	@Deprecated // 表明say方法已过时,这样做好处:以前仍使用该代码的开发人员依然程序可以执行成功
	// 后来的开发人员在看到这个标记:爷们,这个方法过时了,尽量别用,你看看有没有别的替代方法,在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告.
	public static void say() {
		System.out.println("say sth...");
	}
}

class Person {
	private String name;
	private int age;

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override // 加上这个说明一定要复写,不复写在编译时期发生:
				// AnnotationTest.java:45: 错误: 方法不会覆盖或实现超类型的方法
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

}

 

注解的生命周期:

 

  Retention(保留):

    注解的生命周期:

    RetentionPolicy.SOURCE:

          仅仅给编译器看的,编译器检查完丢掉

          例如:@Override 强制要求复写掉父类方法->不复写编译时期报错

                  @SuppressWarnings 抑制警告->编译器:不让我警告我就什么也不报

                  RetentionPolicy.CLASS:(默认)

                  从.java保留到.class但是被类加载器加载到虚拟机中时会去掉

          例如:通过反射将拿不到注解类的实例

                  RetentionPolicy.RUNTIME:

                  直到运行阶段注解依然存在    

          例如:@Deprecated:不但在编译时期检测方法是否过时,在运行时期依然会检测方法的字节码

 

 

自定义注解与为注解添加属性:

 

元注解:注解上的注解,例如@Retention,@Target

public @interface MetaAnnotation {
	  String value() default "Meta";
}
// 反编译:
public interface Test extends Annotation {
	public abstract String value();
}

 

package temp;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.ElementType;

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE }) // TYPE:Type 是 Java
													// 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。													// 在这里TYPE表示:类、接口(包括注释类型)或枚举声明													// Target这个注解指明下面的自定义注解可以使用的位置
public @interface CustomAnnotation {
	// 有一个抽象方法
	public abstract String color() default "black";// 为注解增加了一个属性color													// 指定默认值为black
	String value() default "white";// 增加一个value属性
	int[] arrAttri() default { 1, 2, 3 };// arrAttri属性类型为int[]
	TrafficLamp lamp() default TrafficLamp.RED; // lamp属性类型为枚举
	Class<?> cls() default CustomAnnotation.class;// 属性类型为Class
	// 较为复杂
	MetaAnnotation ma() default @MetaAnnotation("MetaAnnotation");// 属性类型为一个注解类型,																	// 默认值是MetaAnnotation一个实例对象
}

/*
 * ElementType的枚举常量: ANNOTATION_TYPE 注释类型声明 CONSTRUCTOR 构造方法声明 FIELD
 * 字段声明(包括枚举常量) LOCAL_VARIABLE 局部变量声明 METHOD 方法声明 PACKAGE 包声明 PARAMETER 参数声明
 * TYPE 类、接口(包括注释类型)或枚举声明
 */

 

 

使用注解中的属性: 

@CustomAnnotation
public class AnnotationDemo {

	public static CustomAnnotation getAnnotationOnMethod(String methodName) throws Exception {
		Method method = AnnotationDemo.class.getMethod(methodName);
		return method.getAnnotation(CustomAnnotation.class);
	}
	@CustomAnnotation("black") // 应用注解的属性
								// 如果注解类中有一个属性为String
								// value();(不一定为String,只要属性名为value均可)
								// 可以将value="black"等价于"black"(即其他属性都采用默认值或者你只有一个value属性)
								// 例如:@Retention(RetentionPolicy.RUNTIME)-->内部属性RetentionPolicy
								// value();
	public static void value() throws Exception {
		CustomAnnotation ca = getAnnotationOnMethod("value");
		System.out.println("value: " + ca.value());// black
	}
	@CustomAnnotation(arrAttri = { 4, 5 }) // 如果数组元素只有一个简写为arrAttri=6
	public static void arrAttri() throws Exception {
		CustomAnnotation ca = getAnnotationOnMethod("arrAttri");
		System.out.println("arrAttri: " + ca.arrAttri().length);// 2
	}
	@CustomAnnotation(lamp = TrafficLamp.RED)
	public static void lamp() throws Exception {
		CustomAnnotation ca = getAnnotationOnMethod("lamp");
		System.out.println("lamp: " + ca.lamp().nextLamp());// GREEN
	}
	@CustomAnnotation(ma = @MetaAnnotation("ma"))
	public static void metaAnnotation() throws Exception {
		CustomAnnotation ca = getAnnotationOnMethod("metaAnnotation");
		System.out.println("ma: " + ca.ma().value());
	}
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		CustomAnnotation ca = AnnotationDemo.class.getAnnotation(CustomAnnotation.class);// 将获取类AnnotationDemo上的CustomAnnotation注解的一个实例,没有返回null
		System.out.println(ca + "\n");
		value();
		arrAttri();
		lamp();
		metaAnnotation();
	}
}

 

 

2.泛型

 

泛型&反射:

package temp;
/*
泛型术语:
 ArrayList<E>:泛型类型
             :E称为类型变量/类型参数
 ArrayList<Integer>:参数化的类型
                   :Integer称为实际类型参数              
                    :<>typeof
  ArrayList:原始类型(rawtype)
*/

import java.lang.reflect.Constructor;

public class GenericDemo1 {

	public static void main(String[] args) throws Exception {
		/*
		 * Class<T>: T - 由此 Class 对象建模的类的类型。例如,String.class 的类型是
		 * Class<String>。如果将被建模的类未知,则使用 Class<?>。 Constructor<T> T -在其中声明构造方法的类。
		 * public T newInstance(Object... initargs)//返回值类型为T
		 */
		Constructor<String> con = String.class.getConstructor();
		String str = con.newInstance();
	}

}
/*
 * 未使用泛型前,集合中可以存入任意引用类型的元素(Object)->安全隐患->在取出元素时进行强转->运行时可能发生ClassCastException
 * 使用泛型后,限定集合中的元素类型为一个特定类型,集合中只能存储同一个类型的对象 1.将运行时期的的安全隐患转移到了编译时期 2.避免了强制转换的麻烦
 */

 

类型参数的类型判断

/*
 类型参数的类型推断总结:
1.
  static <E> void swap(E[] a, int i, int j)
  swap(new String[3],3,4)
  ->推断出E为String

2.
  static <T> void add(T a, T b) 
  add(3,5)
  T->Integer
 
  static <T> void add(T a, T b) 
  add(3.1,5)
  T->Number//取两者最小父类
 
  static <T> T add(T a, T b) 
  Number num=add(3.1,5)
    这时候以返回值的实际参数类型为主:String->T->String,编译器报错,Number num=add(3.1,5)可以

3.
     static <T> void copy(T[] a,T[]  b)
     copy(new Integer[5],new String[5])
     OK,编译器推断出类型变量T为Number
     
     static <T> void copy(Collection<T> a , T[] b)
     copy(new Vector<String>(), new Integer[5])
           编译器报错:根据参数化的Vector类实例将类型变量直接确定为String类型->
                   T就是String,那么第二个形参的类型变量T为String
*/

 

如何获取泛型中的实际类型参数:

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.HashMap;

public class GenericReflect {

	public static void main(String[] args) throws Exception {
		// 如何通过反射来获得泛型中的实际类型参数?
		// 必须通过一个方法来获取,因为方法对象提供有获取形参类型的方法,由于泛型的实际类型参数在编译后被擦除,不能直接通过反射获取
		Method method = GenericReflect.class.getMethod("getParas", HashMap.class);
		Type[] type = method.getGenericParameterTypes();// 如果形参类型是参数化类型,则为其返回的对象必须实际反映源代码中使用的实际类型参数如果形参类型是类型变量或参数化类型,则创建它。否则将解析它。
		System.out.println(type[0]);
		// System.out.println(actua	lType[0] + "\n" + actualType[1]);
	}

	/* 通过反射获取泛型中的实际类型参数 */
	public static void getParas(HashMap<Integer, String> hs) {

	}
}

 

 

 

 

 

1
1
分享到:
评论

相关推荐

    java泛型反射注解

    先说一下遇到的问题:通过使用GSON泛型进行报文转换的时候想要对部分关键字段加密,发现在封装好的方法中,对个别字段的加密满足不了。 解决过程:首先通过反射获取到bean下的对象名称。 对象名称获取到了之后需要...

    利用java反射、注解及泛型模拟ORM实现

    在Java编程中,反射、注解(Annotation)和泛型是三个非常重要的特性,它们各自在不同的场景下发挥着关键作用。这篇博文“利用java反射、注解及泛型模拟ORM实现”旨在探讨如何结合这三种技术来实现对象关系映射(ORM...

    Java基础入门四泛型反射注解.pdf

    在Java基础入门四泛型、反射、注解的学习中,我们会了解到如何正确使用泛型来创建更加健壮的代码,如何利用反射机制实现类和对象的动态操作,以及如何利用注解来简化开发过程和提高代码的可读性。 此外,文档中提到...

    Java反射、泛型和注解实战之Spring核心注入IOC的实现

    在Java编程领域,反射、泛型和注解是三个非常重要的特性,它们为代码提供了高度的灵活性和可扩展性。在本实战项目中,我们将深入探讨如何利用这些特性实现一个类似Spring框架的核心注入机制,即控制反转(Inversion ...

    JAVA设计模式--程序设计--反射--注解--泛型

    Java设计模式、程序设计、反射、注解和泛型是Java开发中的核心概念,它们各自在不同的场景下发挥着重要作用,构建出高效、可维护的软件系统。 首先,Java设计模式是面向对象编程中的一种最佳实践,是解决常见问题的...

    java5泛型新特性 pdf

    Java 5 泛型是Java编程语言中一个重要的里程碑,它引入了类型安全的集合,大大增强了代码的可读性和可维护性。泛型在Java 5中首次亮相,为开发者提供了一种方式来限制集合(如List、Set、Map等)中可以存储的数据...

    Java-Java反射与泛型教程

    Java反射与泛型是Java编程中的两个重要特性,它们各自为开发者提供了强大的工具来增强代码的灵活性和类型安全性。在本教程中,我们将深入探讨这两个主题,帮助你更好地理解和运用它们。 **Java反射** Java反射机制...

    Java中泛型的各种使用

    在Java编程语言中,泛型(Generic)是一个强大的特性,它允许我们在编译时检查类型安全,并且可以消除运行时的类型转换。泛型引入的主要目的是提高代码的可读性和可维护性,同时减少类型转换的冗余。下面将详细讨论...

    Java泛型实例

    Java泛型是Java编程语言中的一个重要特性,它在2004年随着Java SE 5.0的发布而引入。这个特性允许程序员在定义类、接口和方法时声明类型参数,从而增强了代码的类型安全性和重用性。通过使用泛型,我们可以编写更加...

    Struts2 Spring3 Hibernate 注解功能 DAO 泛型 通用分页

    在这个项目"SSHWithAnnotationDemo"中,开发者利用注解功能,DAO泛型以及通用分页技术,进一步优化了代码结构和用户体验。 首先,让我们深入了解一下Struts2、Spring3和Hibernate的核心功能: 1. **Struts2**:这...

    S2SH整合例子 注解配置 JSON 泛型Dao

    4. **注解配置**:在现代Java开发中,注解(Annotation)被广泛使用来替代XML配置,简化代码并提高可读性。在S2SH整合中,比如在Spring中可以使用`@Component`、`@Service`、`@Repository`、`@Controller`等注解声明...

    反射操作注解与反射操作泛型.docx

    本文将详细介绍反射操作和泛型在 Java 编程中的应用,特别是结合注解(Annotation)和对象关系映射(ORM)的使用。 一、反射操作 反射操作是 Java 语言中的一种机制,允许程序在运行时检查和修改类、对象、方法、...

    java内置注解

    Java内置注解是Java语言中的一种元编程机制,它们为代码提供信息,这些信息可以被编译器或运行时环境用来执行特定的操作。...所以,这个视频教程对于想要深入了解Java注解的开发者来说,无疑是一个非常宝贵的资源。

    Java5.0泛型编程

    Java5.0泛型编程是Java开发中的一个重要里程碑,它引入了一种强大的类型系统机制,大大增强了代码的类型安全性,并减少了在编译期间和运行时出现的类型转换错误。这一特性使得开发者能够在编写代码时就能明确指定...

    重新理解Java泛型

    Java泛型是Java编程语言中的一个重要特性,它允许在类、接口和方法中使用类型参数,从而提高了代码的类型安全性和可复用性。本文旨在深入解析Java泛型的各个方面,帮助开发者形成全面、清晰的理解。 1. **泛型基础*...

    java反射、泛型、注解、代理精讲

    本课程是《 java就业班》系统课程的第24章,全套课程精细讲解,该课程超过其他机构30%的课程量,经过我们全套课程系统学习的同学,可轻松从事Java高级工程师或系统架构师岗位,课程提供全套代码笔记其它相关素材及...

    java多线程反射泛型及正则表达式学习笔记和源码.zip

    Java编程语言以其强大的功能和广泛的应用领域而备受程序员青睐,特别是在多线程、反射、泛型和正则表达式这四个关键概念上,Java展现出了卓越的灵活性和可扩展性。下面将对这些主题进行深入的探讨。 首先,让我们来...

    java进阶技术:泛型、反射、注解

    泛型是Java SE 1.5的新特性,好处是在编译时检查类型安全,并且所有的强制转换都是自动和隐式的,以提高代码的重用率。JAVA反射机制是构建框架技术的基础所在。灵活掌握Java反射机制,对以后学习框架有很大的帮助。...

    java基础入门&demo.zip

    在这个压缩包中,包含了一个名为"java基础入门&demo.docx"的文档,我们可以假设它是详细的教学材料或示例代码的解释。 首先,Java基础入门通常会涵盖以下几个核心概念: 1. **环境配置**:安装Java Development ...

Global site tag (gtag.js) - Google Analytics