小言_互联网的博客

Java注解及反射(一):

364人阅读  评论(0)

Java注解:

注解可以分为内置注解,元注解,以及自定义注解。

内置注解包括:

@Override//重写超类中的另一个方法

@Deprecated//表示不建议使用这样的元素

@SuppressWarnings//用来抑制编译时的警告信息

元注解:

负责注解其他注解

它们所支持的类在java.lang.annotation包中可以找到

@Target://用于描述注解适用范围

@Retention://表示需要在什么级别保存该注释信息,用于描述注解的生命周期

(SOURCE < CLASS < RUNTIME)

@Document://说明该注解被包含在javadoc中

@Inherited://说明子类可以继承父类中的该注解

自定义注解:

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

public class Test01 {
    @MyAnnotation(schools = {"hello"})
    public void hello(){

    }
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
    String name() default "";
    int age() default 18;
    String[] schools();
}

这里自定义注解的里面不是方法而是参数,需要的参数,可以给他们设默认值;

如果只有一个参数建议声明为String value();

因为你在@MyAnnotation(“aaa”)中可以不用带参数名传值

若为String name();

则为@MyAnnotation(name = “aaa”);

动态语言例如:python,JavaScript,php这些,它们可以在运行时可以根据某些条件改变自身的结构。

function f(){
	//x静态字符串
	var x = "var a = 3; var b = 4; alert(a + b)"
	//执行x时会执行x包含的这段代码,x = 7;
	eval(x);
}

Java是一个静态语言,通过反射使Java成为动态性

反射:

正常方式:

反射方式:

​ 加载完类之后,在堆内存的方法去就产生了一个Class类型对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息,我们可以通过这个对象看到类的结构,这个对象就像一面镜子,透过这个镜子看到类的结构,所以称为反射。

反射优缺点:

优点:

​ 可以实现动态创建对象和编译,具有很大的灵活性

缺点:

​ 对性能有所影响。反射基本是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于直接执行相同的操作。

public class Test02 {
    //通过反射方法获取class对象
    public static void main(String[] args) throws ClassNotFoundException{
        Class c1 = Class.forName("User");
        System.out.println(c1);
        Class c2 = Class.forName("User");
        Class c3 = Class.forName("User");
        Class c4 = Class.forName("User");

        //一个类在内存中只有一个Class对象
        //一个类被加载,类的整个结构都会被封装在Class对象中
        System.out.println(c2.hashCode());
        System.out.println(c3.hashCode());
        System.out.println(c4.hashCode());
        //打印出的hash值相同证明一个类在内存中只有一个Class对象
    }
}

//实体类
class User{
    private String name;
    private int age;
    private int id;

    public User(){

    }

    public User(String name, int age, int id) {
        this.name = name;
        this.age = age;
        this.id = id;
    }

	.....//getter and setter
}

可以通过对象反射求出类的名称!

Class本身也是一个类;

Class对象只能由系统建立对象;

每个实例都会记得自己是由哪个Class实例所生产;

Class类是Reflection的根源;

获取Class类的实例:

a)若已知具体的类,通过类的class属性获取,该方法最安全可靠,程序性能最高:

​ Class c1 = Person.class;

b)若已知某个类的实例,调用该实例getClass()方法获取Class对象

​ Class c1 = person.getClass();

c)已知一个类的全类名,且该类在类路径下,可通过Class类的静态方法forName()获取,可能

抛出ClassNotFoundException

​ Class c1 = Class.forName(“demo()1.Student”);

d)内置基本数据类型可以直接用类名.Type

e)还可以利用ClassLoader

public class Test03 {
    public static void main(String[] args) throws ClassNotFoundException{
        Person person = new Student();
        System.out.println("这个人是:" + person.name);
        //方法一:通过对象获得
        Class c1 = person.getClass();
        System.out.println(c1.hashCode());

        //方法二:forName获得
        Class c2 = Class.forName("Student");
        System.out.println(c2.hashCode());

        //方法三:通过类名.class获得
        Class c3 = Student.class;
        System.out.println(c3.hashCode());

        //方法四:基本内置类型的包装类都有一个Tyoe属性
        Class c4 = Integer.TYPE;
        System.out.println(c4);

        //获得父类的类型
        Class c5 = c1.getSuperclass();
        System.out.println(c5);
    }
}

class Person{
    String name;

    Person(){

    }

    public Person(String name) {
        this.name = name;
    }
	//getter and setter
}

class Student extends Person{
    public Student(){
        this.name = "学生";
    }
}

class Teacher extends Person{
    public Teacher(){
        this.name = "教师";
    }
}

}
//getter and setter
}

class Student extends Person{
public Student(){
this.name = “学生”;
}
}

class Teacher extends Person{
public Teacher(){
this.name = “教师”;
}
}



转载:https://blog.csdn.net/Jason_curry/article/details/105478497
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场