浅谈Java自定义注解和运行时靠反射获取注解

java自定义注解

Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。

注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。

1、元注解

元注解是指注解的注解。包括  @Retention @Target @Document @Inherited四种。

1.1、@Retention: 定义注解的保留策略

@Retention(RetentionPolicy.SOURCE)  //注解仅存在于源码中,在class字节码文件中不包含
@Retention(RetentionPolicy.CLASS)   // 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得,
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到

注解类:

@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Target({ElementType.FIELD,ElementType.METHOD})//定义注解的作用目标**作用范围字段、枚举的常量/方法
@Documented//说明该注解将被包含在javadoc中
public @interface FieldMeta {

	/**
	 * 是否为序列号
	 * @return
	 */
	boolean id() default false;
	/**
	 * 字段名称
	 * @return
	 */
	String name() default "";
	/**
	 * 是否可编辑
	 * @return
	 */
	boolean editable() default true;
	/**
	 * 是否在列表中显示
	 * @return
	 */
	boolean summary() default true;
	/**
	 * 字段描述
	 * @return
	 */
	String description() default "";
	/**
	 * 排序字段
	 * @return
	 */
	int order() default 0;
}

实体类:

public class Anno {

	@FieldMeta(id=true,name="序列号",order=1)
	private int id;
	@FieldMeta(name="姓名",order=3)
	private String name;
	@FieldMeta(name="年龄",order=2)
	private int age;

	@FieldMeta(description="描述",order=4)
	public String desc(){
		return "java反射获取annotation的测试";
	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}

}

获取到注解的帮助类:

public class SortableField {

	public SortableField(){}

	public SortableField(FieldMeta meta, Field field) {
		super();
		this.meta = meta;
		this.field = field;
		this.name=field.getName();
		this.type=field.getType();
	}

	public SortableField(FieldMeta meta, String name, Class<?> type) {
		super();
		this.meta = meta;
		this.name = name;
		this.type = type;
	}

	private FieldMeta meta;
	private Field field;
	private String name;
	private Class<?> type;

	public FieldMeta getMeta() {
		return meta;
	}
	public void setMeta(FieldMeta meta) {
		this.meta = meta;
	}
	public Field getField() {
		return field;
	}
	public void setField(Field field) {
		this.field = field;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	public Class<?> getType() {
		return type;
	}

	public void setType(Class<?> type) {
		this.type = type;
	}

}

运行时获取注解,首先创建一个基类:

public class Parent<T> {

	private Class<T> entity;

	public Parent() {
		init();
	}

	@SuppressWarnings("unchecked")
	public List<SortableField> init(){
		List<SortableField> list = new ArrayList<SortableField>();
		/**getClass().getGenericSuperclass()返回表示此 Class 所表示的实体(类、接口、基本类型或 void)
		 * 的直接超类的 Type(Class<T>泛型中的类型),然后将其转换ParameterizedType。。
		 * 	getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组。
		 * 	[0]就是这个数组中第一个了。。
		 * 	简而言之就是获得超类的泛型参数的实际类型。。*/
		entity = (Class<T>)((ParameterizedType)this.getClass().getGenericSuperclass())
				.getActualTypeArguments()[0];
//		FieldMeta filed = entity.getAnnotation(FieldMeta.class);

		if(this.entity!=null){

			/**返回类中所有字段,包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段
			 * entity.getFields();只返回对象所表示的类或接口的所有可访问公共字段
			 * 在class中getDeclared**()方法返回的都是所有访问权限的字段、方法等;
			 * 可看API
			 * */
			Field[] fields = entity.getDeclaredFields();
//
			for(Field f : fields){
				//获取字段中包含fieldMeta的注解
				FieldMeta meta = f.getAnnotation(FieldMeta.class);
				if(meta!=null){
					SortableField sf = new SortableField(meta, f);
					list.add(sf);
				}
			}

			//返回对象所表示的类或接口的所有可访问公共方法
			Method[] methods = entity.getMethods();

			for(Method m:methods){
				FieldMeta meta = m.getAnnotation(FieldMeta.class);
				if(meta!=null){
					SortableField sf = new SortableField(meta,m.getName(),m.getReturnType());
					list.add(sf);
				}
			}
			//这种方法是新建FieldSortCom类实现Comparator接口,来重写compare方法实现排序
//			Collections.sort(list, new FieldSortCom());
			Collections.sort(list, new Comparator<SortableField>() {
				@Override
				public int compare(SortableField s1,SortableField s2) {
					return s1.getMeta().order()-s2.getMeta().order();
//					return s1.getName().compareTo(s2.getName());//也可以用compare来比较
				}

			});
		}
		return list;

	}
}

创建子类继承基类:

public class Child extends Parent<Anno>{

}

测试类:

public class TestAnnotation {

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static void main(String[] args) {
		Parent c = new Child();
		List<SortableField> list = c.init();//获取泛型中类里面的注解
		//输出结果
		for(SortableField l : list){
			System.out.println("字段名称:"+l.getName()+"\t字段类型:"+l.getType()+
					"\t注解名称:"+l.getMeta().name()+"\t注解描述:"+l.getMeta().description());
		}
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////

1、Annotation的工作原理:

JDK5.0中提供了注解的功能,允许开发者定义和使用自己的注解类型。该功能由一个定义注解类型的语法和描述一个注解声明的语法,读取注解的API,一个使用注解修饰的class文件和一个注解处理工具组成。

Annotation并不直接影响代码的语义,但是他可以被看做是程序的工具或者类库。它会反过来对正在运行的程序语义有所影响。

Annotation可以冲源文件、class文件或者在运行时通过反射机制多种方式被读取。

2、@Override注解:

java.lang

注释类型 Override
@Target(value=METHOD)
@Retention(value=SOURCE)
public @interface Override表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。

@Override注解表示子类要重写父类的对应方法。

Override是一个Marker annotation,用于标识的Annotation,Annotation名称本身表示了要给工具程序的信息。

下面是一个使用@Override注解的例子:

class A {
  private String id;
  A(String id){
    this.id = id;
  }
  @Override
  public String toString() {
    return id;
  }
}

3、@Deprecated注解:

java.lang
注释类型 Deprecated
@Documented
@Retention(value=RUNTIME)

public @interface Deprecated用 @Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。

@Deprecated注解表示方法是不被建议使用的。

Deprecated是一个Marker annotation。

下面是一个使用@Deprecated注解的例子:

class A {
  private String id;
  A(String id){
    this.id = id;
  }
  @Deprecated
  public void execute(){
    System.out.println(id);
  }
  public static void main(String[] args) {
    A a = new A("a123");
    a.execute();
  }
}

4、@SuppressWarnings注解:

java.lang
注释类型 SuppressWarnings
@Target(value={TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})
@Retention(value=SOURCE)

public @interface SuppressWarnings指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。注意,在给定元素中取消显示的警告集是所有包含元素中取消显示的警告的超集。例如,如果注释一个类来取消显示某个警告,同时注释一个方法来取消显示另一个警告,那么将在此方法中同时取消显示这两个警告。

根据风格不同,程序员应该始终在最里层的嵌套元素上使用此注释,在那里使用才有效。如果要在特定的方法中取消显示某个警告,则应该注释该方法而不是注释它的类。

@SuppressWarnings注解表示抑制警告。

下面是一个使用@SuppressWarnings注解的例子:

@SuppressWarnings("unchecked")
public static void main(String[] args) {
  List list = new ArrayList();
  list.add("abc");
}

5、自定义注解:

使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。

自定义最简单的注解:

public @interface MyAnnotation {

}

使用自定义注解:

public class AnnotationTest2 {

  @MyAnnotation
  public void execute(){
    System.out.println("method");
  }
}

5.1、添加变量:

public @interface MyAnnotation {

  String value1();
}

使用自定义注解:

public class AnnotationTest2 {

  @MyAnnotation(value1="abc")
  public void execute(){
    System.out.println("method");
  }
}

当注解中使用的属性名为value时,对其赋值时可以不指定属性的名称而直接写上属性值接口;除了value意外的变量名都需要使用name=value的方式赋值。

5.2、添加默认值:

public @interface MyAnnotation {

  String value1() default "abc";
}

5.3、多变量使用枚举:

public @interface MyAnnotation {

  String value1() default "abc";
  MyEnum value2() default MyEnum.Sunny;
}
enum MyEnum{
  Sunny,Rainy
}

使用自定义注解:

public class AnnotationTest2 {

  @MyAnnotation(value1="a", value2=MyEnum.Sunny)
  public void execute(){
    System.out.println("method");
  }
}

5.4、数组变量:

public @interface MyAnnotation {

  String[] value1() default "abc";
}

使用自定义注解:

public class AnnotationTest2 {

  @MyAnnotation(value1={"a","b"})
  public void execute(){
    System.out.println("method");
  }
}

6、设置注解的作用范围:

@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)

public @interface Retention指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS。

只有元注释类型直接用于注释时,Target 元注释才有效。如果元注释类型用作另一种注释类型的成员,则无效。

public enum RetentionPolicy
extends Enum<RetentionPolicy>注释保留策略。此枚举类型的常量描述保留注释的不同策略。它们与 Retention 元注释类型一起使用,以指定保留多长的注释。

CLASS
编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。

RUNTIME
编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。

SOURCE
编译器要丢弃的注释。@Retention注解可以在定义注解时为编译程序提供注解的保留策略。

属于CLASS保留策略的注解有@SuppressWarnings,该注解信息不会存储于.class文件。

6.1、在自定义注解中的使用例子:

@Retention(RetentionPolicy.CLASS)
public @interface MyAnnotation {

  String[] value1() default "abc";
}

7、使用反射读取RUNTIME保留策略的Annotation信息的例子:

java.lang.reflect

接口 AnnotatedElement

所有已知实现类:

AccessibleObject, Class, Constructor, Field, Method, Package表示目前正在此 VM 中运行的程序的一个已注释元素。该接口允许反射性地读取注释。由此接口中的方法返回的所有注释都是不可变并且可序列化的。调用者可以修改已赋值数组枚举成员的访问器返回的数组;这不会对其他调用者返回的数组产生任何影响。

如果此接口中的方法返回的注释(直接或间接地)包含一个已赋值的 Class 成员,该成员引用了一个在此 VM 中不可访问的类,则试图通过在返回的注释上调用相关的类返回的方法来读取该类,将导致一个 TypeNotPresentException。

isAnnotationPresent
boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。此方法主要是为了便于访问标记注释而设计的。

参数:

annotationClass - 对应于注释类型的 Class 对象

返回:

如果指定注释类型的注释存在于此对象上,则返回 true,否则返回 false

抛出:

NullPointerException - 如果给定的注释类为 null

从以下版本开始:

1.5

getAnnotation
<T extends Annotation> T getAnnotation(Class<T> annotationClass)如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。

参数:

annotationClass - 对应于注释类型的 Class 对象

返回:

如果该元素的指定注释类型的注释存在于此对象上,则返回这些注释,否则返回 null

抛出:

NullPointerException - 如果给定的注释类为 null

从以下版本开始:

1.5

getAnnotations
Annotation[] getAnnotations()返回此元素上存在的所有注释。(如果此元素没有注释,则返回长度为零的数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。

返回:

此元素上存在的所有注释

从以下版本开始:

1.5

getDeclaredAnnotations
Annotation[] getDeclaredAnnotations()返回直接存在于此元素上的所有注释。与此接口中的其他方法不同,该方法将忽略继承的注释。(如果没有注释直接存在于此元素上,则返回长度为零的一个数组。)该方法的调用者可以随意修改返回的数组;这不会对其他调用者返回的数组产生任何影响。

返回:

直接存在于此元素上的所有注释

从以下版本开始:

1.5

下面是使用反射读取RUNTIME保留策略的Annotation信息的例子:

自定义注解:

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

  String[] value1() default "abc";
}

使用自定义注解:

public class AnnotationTest2 {

  @MyAnnotation(value1={"a","b"})
  @Deprecated
  public void execute(){
    System.out.println("method");
  }
}

读取注解中的信息:

public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
  AnnotationTest2 annotationTest2 = new AnnotationTest2();
  //获取AnnotationTest2的Class实例
  Class<AnnotationTest2> c = AnnotationTest2.class;
  //获取需要处理的方法Method实例
  Method method = c.getMethod("execute", new Class[]{});
  //判断该方法是否包含MyAnnotation注解
  if(method.isAnnotationPresent(MyAnnotation.class)){
    //获取该方法的MyAnnotation注解实例
    MyAnnotation myAnnotation = method.getAnnotation(MyAnnotation.class);
    //执行该方法
    method.invoke(annotationTest2, new Object[]{});
    //获取myAnnotation
    String[] value1 = myAnnotation.value1();
    System.out.println(value1[0]);
  }
  //获取方法上的所有注解
  Annotation[] annotations = method.getAnnotations();
  for(Annotation annotation : annotations){
    System.out.println(annotation);
  }
}

8、限定注解的使用:

限定注解使用@Target。

@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)

public @interface Target指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在 Target 元注释,则声明的类型可以用在任一程序元素上。如果存在这样的元注释,则编译器强制实施指定的使用限制。 例如,此元注释指示该声明类型是其自身,即元注释类型。它只能用在注释类型声明上:

@Target(ElementType.ANNOTATION_TYPE)
  public @interface MetaAnnotationType {
    ...
  }

此元注释指示该声明类型只可作为复杂注释类型声明中的成员类型使用。它不能直接用于注释:

@Target({})
  public @interface MemberType {
    ...
  }

这是一个编译时错误,它表明一个 ElementType 常量在 Target 注释中出现了不只一次。例如,以下元注释是非法的:

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.FIELD})
  public @interface Bogus {
    ...
  }public enum ElementType

extends Enum<ElementType>程序元素类型。此枚举类型的常量提供了 Java 程序中声明的元素的简单分类。

这些常量与 Target 元注释类型一起使用,以指定在什么情况下使用注释类型是合法的。

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

注解的使用限定的例子:

@Target(ElementType.METHOD)
public @interface MyAnnotation {

  String[] value1() default "abc";
}

9、在帮助文档中加入注解:

要想在制作JavaDoc文件的同时将注解信息加入到API文件中,可以使用java.lang.annotation.Documented。

在自定义注解中声明构建注解文档:

@Documented
public @interface MyAnnotation {

  String[] value1() default "abc";
}

使用自定义注解:

public class AnnotationTest2 {

  @MyAnnotation(value1={"a","b"})
  public void execute(){
    System.out.println("method");
  }
}

10、在注解中使用继承:

默认情况下注解并不会被继承到子类中,可以在自定义注解时加上java.lang.annotation.Inherited注解声明使用继承。

@Documented
@Retention(value=RUNTIME)
@Target(value=ANNOTATION_TYPE)
public @interface Inherited指示注释类型被自动继承。如果在注释类型声明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。此过程会重复进行,直到找到此类型的注释或到达了该类层次结构的顶层 (Object) 为止。如果没有超类具有该类型的注释,则查询将指示当前类没有这样的注释。

注意,如果使用注释类型注释类以外的任何事物,此元注释类型都是无效的。还要注意,此元注释仅促成从超类继承注释;对已实现接口的注释无效。

以上这篇浅谈Java自定义注解和运行时靠反射获取注解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Java 自定义注解及利用反射读取注解的实例

    一.自定义注解 元注解: @interface注解: 定义注解接口 @Target注解: 用于约束被描述的注解的使用范围,当被描述的注解超出使用范围则编译失败.如:ElementType.METHOD,ElementType.TYPE: @Retention 注解:用于约束被定义注解的作用范围,作用范围有三个: 1.RetentionPolicy.SOURCE:作用范围是源码,作用于Java文件中,当执行javac时去除该注解. 2.RetentionPolicy.CLASS:作用范围是二进制码

  • 浅谈java反射和自定义注解的综合应用实例

    前言 前几天学习了反射和自定义注解,刚好工作中遇到一个小问题:前台传递到后台的必填字段为空,导致不能插入数据库.就是这样一个小问题,让我考虑到是否可以做一个通用的方法,让前台传递过来的必填字段在后台也校验一遍,如果传递为空,则把响应字段返回提示.因此,我考虑的是用注解的方式,在必填字段上面定义,利用反射得到必填字段的字段名,判断是否为空,并返回响应的信息. 需求模拟 假设客户有:姓名,年龄,地址,手机号码,身份证号等信息,而我们是做金融业务,所以关键是看客户的三要素:姓名,身份证号,手机号码.我

  • java 注解annotation的使用以及反射如何获取注解

     一.注解基本知识 1.元注解 元注解是指注解的注解.包括  @Retention @Target @Document @Inherited四种. 1. Annotation型定义为@interface, 所有的Annotation会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或是接口. 2. 参数成员只能用public或默认(default)这两个访问权修饰 3. 参数成员只能用基本类型byte,short,char,int,long,float,doubl

  • java基础之反射和泛型以及注解

     java基础之反射和泛型以及注解 泛型擦除 泛型擦除: 泛型只在编译时期有效,编译后的字节码文件中不存在泛型信息. 声明泛型集合,集合两端类型必须一致.类型也可以用包装类型,泛型的类型必须是引用类型,不能为基本类型. 实现公用的类和方法,对公用的业务进行抽取. 泛型方法/泛型类/泛型接口 public class GenericTest { /** * 泛型声明,定义泛型方法 * @param <T> * @param <K> * @param t * @param k */ p

  • Java利用反射如何查找使用指定注解的类详解

    前言 最近有些空,想自己写个跟spring里的注解一样的注解来用,然后希望能找到使用了自己写了注解的类,下面来介绍一下实现方法 声明,下面代码是没看过spring源码写的,基本上都是网上找的博客,整理的 定义注解 Controller.java @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Controller { } RequestMapping.jav

  • Java利用自定义注解、反射实现简单BaseDao实例

    在常见的ORM框架中,大都提供了使用注解方式来实现entity与数据库的映射,这里简单地使用自定义注解与反射来生成可执行的sql语句. 这是整体的目录结构,本来是为复习注解建立的项目^.^ 好的,首先我们来确定思路. 1. 自定义@Table @Column注解, 我们稍微模仿hibernate,让@Table作用于类上,来表明实体类与数据表的映射关系,且让@Table中的属性value映射为数据表的名称tableName:让@Column作用于属性上(这里没实现作用于set方法上),表明属性与

  • 浅谈Java自定义注解和运行时靠反射获取注解

    java自定义注解 Java注解是附加在代码中的一些元信息,用于一些工具在编译.运行时进行解析和使用,起到说明.配置的功能. 注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用.包含在 java.lang.annotation 包中. 1.元注解 元注解是指注解的注解.包括  @Retention @Target @Document @Inherited四种. 1.1.@Retention: 定义注解的保留策略 @Retention(RetentionPolicy.SOURCE) //注解仅

  • 浅谈Java自定义注解相关知识

    一.自定义注解格式 分析 Java 中自带的 @Override 注解 , 源码如下 : @Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { } 注解分为两部分 : ① 元注解 ; ② public @interface 注解名称 ; 二.注解本质分析 按照 public @interface 注解名称 格式 , 写出一个注解 , 编译该注解代码生成 Annotat

  • 浅谈Java自定义类加载器及JVM自带的类加载器之间的交互关系

    JVM自带的类加载器: 其关系如下: 其中,类加载器在加载类的时候是使用了所谓的"父委托"机制.其中,除了根类加载器以外,其他的类加载器都有且只有一个父类加载器. 关于父委托机制的说明: 当生成 一个自定义的类加载器实例时,如果没有指定它的父加载器,那么系统类加载器将成为该类加载器的父类加载器 下面,自定义类加载器.自定义的类加载器必须继承java.lang.ClassLoader类 import java.io.*; public class MyClassLoader extend

  • 浅谈Java中注解Annotation的定义、使用、解析

    此例子,用于说明如何在Java中对"注解 Annotation"的定义.使用和解析的操作.注解一般用于自定义开发框架中,至于为什么使用,此处不作过多说明,这里只说明如何使用,以作备记.下面例子已测试,可以正常运行通过. 1.注解自定义. 这里定义两个注解,分别用来注解类和注解属性. package cc.rulian.ann; import java.lang.annotation.ElementType; import java.lang.annotation.Retention;

  • 浅谈java运用注解实现对类中的方法检测的工具

    创建自定义注解 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Test { } 建立测试类 public class UserTest { @Test public void testInsert() { User user = null; System.out.println(user.getUsername()); } @Test public void testQuery(

  • 浅谈Java注解和动态代理

    本文主要介绍Java中与注解和动态代理有关的部分知识,接下来我们看看具体内容. Annotation(注解) 其实就是代码里的特殊标记, 它用于替代配置文件,也就是说,传统方式通过配置文件告诉类如何运行,有了注解技术后,开发人员可以通过注解告诉类如何运行. 1. 三个基本的Annotation: Override:限定重写父类方法, 该注解只能用于方法 Deprecated:用于表示某个程序元素(类, 方法等)已过时 SuppressWarnings:抑制编译器警告. 2.自定义Annotati

  • 浅谈Java垃圾回收的实现过程

    本教程是为了理解基本的Java垃圾回收以及它是如何工作的.这是垃圾回收教程系列的第二部分.希望你已经读过了第一部分:<简单介绍Java垃圾回收机制>. Java垃圾回收是一项自动化的过程,用来管理程序所使用的运行时内存.通过这一自动化过程,JVM解除了程序员在程序中分配和释放内存资源的开销. 启动Java垃圾回收 作为一个自动的过程,程序员不需要在代码中显示地启动垃圾回收过程.System.gc()和Runtime.gc()用来请求JVM启动垃圾回收. 虽然这个请求机制提供给程序员一个启动GC

  • 浅谈java类和对象

    目录 一.面向对象的描述 二.类和对象的基本概念 三.类定义和使用 1.简单认识类 2.类的定义 3.实例化对象 4.类的三大特性 封装 继承 多态 一.面向对象的描述 面向对象是一种现在最为流行的程序设计方法,几乎现在的所有应用都以面向对象为主了,最早的面向对象的概念实际上是由IBM提出的,在70年代的Smaltalk语言之中进行了应用,后来根据面向对象的设计思路,才形成C++,而由C++产生了Java这门面向对象的编程语言. 但是在面向对象设计之前,广泛采用的是面向过程,面向过程只是针对于自

  • 浅谈java Collection中的排序问题

    这里讨论list.set.map的排序,包括按照map的value进行排序. 1)list排序 list排序可以直接采用Collections的sort方法,也可以使用Arrays的sort方法,归根结底Collections就是调用Arrays的sort方法. public static <T> void sort(List<T> list, Comparator<? super T> c) { Object[] a = list.toArray(); Arrays.

  • 浅谈java中的TreeMap 排序与TreeSet 排序

    TreeMap: package com; import java.util.Comparator; import java.util.TreeMap; public class Test5 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub TreeMap<String, String> tree = new TreeMap<String,

随机推荐