注解
什么是注解
package zhujie;
public class TestDome01 {
// @Override 重写的注解
@Override
public String toString() {
return super.toString();
}
}
内置注解
package zhujie;
import java.util.ArrayList;
import java.util.List;
public class TestDome01 {
// @Override 重写的注解
@Override
public String toString() {
return super.toString();
}
// 不推荐程序员使用,但是可以使用,或存在更好的方式
@Deprecated
public static void test(){
System.out.println("Deprecated");
}
@SuppressWarnings("all")
public void test2(){
List list = new ArrayList();
}
public static void main(String[] args) {
test();
}
}
元注解
1.Target
package zhujie;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
// 测试元注解
@MyAnnotation
public class TestDome02 {
@MyAnnotation
public void test(){
}
}
// 定义一个注解
@Target(value ={ElementType.METHOD,ElementType.TYPE}) // 作用域
@interface MyAnnotation{
}
自定义注解
package zhujie;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// 自定义注解
public class TestDome03 {
// 注解可以显示赋值,如果没有默认值,我们就必须给注解赋值
@MyAnnotation2(name = "zcw")
public void test(){
}
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
// 注解的参数:参数类型 + 参数名();
String name() default "";
int age() default 0;
int id() default -1; // 如果默认值为-1,代表不存在
}
反射
优点
:可以实现动态创建对象和编译,体现出很大的灵活性
缺点
:对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的需求。这类操作总是慢于直接执行相同的操作。
获取反射对象
package fanshe;
// 什么家反射
public class Test01 {
public static void main(String[] args) throws ClassNotFoundException {
// 通过反射获取类的class对象
Class c1 = Class.forName("fanshe.User");
System.out.println(c1);
Class c2 = Class.forName("fanshe.User");
Class c3 = Class.forName("fanshe.User");
// 一个类在内存中只会存在一个class对象
// 一个类在加载后,整个类的结构都会封装在Class对象中。
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
}
}
// 实体类:pojo , entity
class User{
private String name;
private int id;
private int age;
public User(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + ''' +
", id=" + id +
", age=" + age +
'}';
}
}
获得class的几种方法
package fanshe;
// 测试class类的创建方式有哪些
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("fanshe.Student");
System.out.println(c2.hashCode());
// 方式三:通过类名.class获得
Class c3 = Student.class;
System.out.println(c3.hashCode());
// 方式四:基本内置类型的包装类都有一个Type属性
Class c4 = Integer.TYPE;
// 获得父类类型
Class c5 = c1.getSuperclass();
System.out.println(c5);
}
}
class Person{
String name;
public Person(String name) {
this.name = name;
}
public Person() {
}
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
'}';
}
}
class Student extends Person {
public Student() {
this.name = "学生";
}
}
class Teacher extends Person {
public Teacher() {
this.name = "老师";
}
}
所有类型的Class对象
package fanshe;
import java.lang.annotation.ElementType;
// 所有类型的Class
public class TestDome04 {
public static void main(String[] args) {
Class c1 = Object.class; // 类
Class c2 = Comparable.class; // 接口
Class c3 = String[].class; // 数组
Class c4 = Override.class; // 注解
Class c5 = ElementType.class; // 枚举
Class c6 = void.class;// void
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
System.out.println(c5);
System.out.println(c6);
}
}
类加载内存
类的加载
类的初始化
package fanshe;
// 测试类什么时候会初始化
public class Test06 {
static {
System.out.println("Main类被加载");
}
public static void main(String[] args) throws ClassNotFoundException {
// 1.主动引用
Son son = new Son(); // Main,Father,Son
// 2.反射也会主动引用
Class.forName("fanshe.Son");// Main,Father,Son
// 不会产生类的引用的方法
System.out.println(Son.b);// Main,Father
System.out.println(Son.M); // Main
}
}
class Father{
static int b = 2;
static {
System.out.println("父类被加载");
}
}
class Son extends Father{
static {
System.out.println("子类被加载");
m = 300;
}
static int m = 100;
static final int M = 1;
}
类加载器
获取类运行时的完整结构
package fanshe;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test08 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class c1 = Class.forName("fanshe.User");
// 获得类的名字
System.out.println(c1.getName()); // 活的包名+类名
System.out.println(c1.getSimpleName()); // 活动类名
// 获得类的属性
Field[] fields = c1.getFields(); // 只能找到public属性
fields = c1.getDeclaredFields(); // 找到全部属性
for (Field field : fields){
System.out.println(field);
}
// 获得指定属性的值
Field name = c1.getDeclaredField("name");
System.out.println(name);
// 获得类的方法
Method[] methods = c1.getMethods(); // 获得本类及其父类的public方法
for (Method method : methods) {
System.out.println("正常的"+method);
}
methods = c1.getDeclaredMethods(); // 获得本类的方法
for (Method method : methods) {
System.out.println("getDeclaredMethods"+method);
}
// 获得制定方法
Method getName = c1.getMethod("getName", null);
Method setName = c1.getMethod("setName", String.class);
System.out.println(getName);
System.out.println(setName);
//获得构造器
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
constructors = c1.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
// 获得指定构造器
Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
System.out.println(declaredConstructor);
}
}
动态创建对象执行方法
package fanshe;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test09 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
// 获得Class对象
Class c1 = Class.forName("fanshe.User");
// 构造一个对象
User user = (User) c1.newInstance(); // 本质是调用了无参构造器
System.out.println(user);
// 通过构造器创建对象
Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
User user2 = (User) constructor.newInstance("zcw", 001, 18);
System.out.println(user2);
// 通过反射调用普通方法
User user3 = (User) c1.getDeclaredConstructor().newInstance();
// 通过反射获取方法
// invoke : 激活 ,(对象,“方法的值”)
Method setName = c1.getDeclaredMethod("setName", String.class);
setName.invoke(user3,"zcw");
System.out.println(user3.getName());
}
}