Java学习_20220628
作者:互联网
注解
1. 注解Annotation的作用:不是程序本身,可以对程序作出解释,可以被其他程序读取。可通过反射机制编程实现这些元数据的访问。
@Override 重写的注解
@Deprecated 不推荐使用,但可以使用
@SuppressWarnings 抑制编译时的警告信息。@SuppressWarnings("all")全部警告;@SuppressWarnings("unchecked")未检查的。
2. 元注解
负责注解其他注解。4个meta-annotation:
@Target 用来描述注解的使用范围(被描述的注解可以用在什么地方)
@Retention 表示需要在什么级别保存该注释信息,用于描述注解的生命周期,表示注解在什么地方有效
@Documented 说明该注解将被包含在javadoc中
@Inherited 说明子类可以继承父类中的该注解
Annotation通常定义
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation1 {
}
(1)使用 @interface 定义注解时,意味着它实现了java.lang.annotation.Annotation 接口,即该注解就是一个Annotation。定义 Annotation 时,@interface 是必须的。通过 @interface 定义注解后,该注解不能继承其他的注解或接口。
(2)@Documented类和方法的 Annotation 在缺省情况下是不出现在 javadoc 中的。如果使用 @Documented 修饰该 Annotation,则表示它可以出现在 javadoc 中。
(3)@Target(ElementType.TYPE),ElementType 是 Annotation 的类型属性。@Target 的作用,就是来指定 Annotation 的类型属性。
public enum ElementType {
TYPE, // 类、接口(包括注释类型)或枚举声明
FIELD, // 字段声明(包括枚举常量)
METHOD, // 方法声明
PARAMETER, //参数声明
CONSTRUCTOR, // 构造方法声明
LOCAL_VARIABLE, // 局部变量声明
ANNOTATION_TYPE, // 注释类型声明
PACKAGE //包声明
}
(4)@Retention(RetentionPolicy.RUNTIME) RetentionPolicy 是 Annotation 的策略属性,而 @Retention 的作用,就是指定 Annotation 的策略属性。
enum RetentionPolicy {
SOURCE, /* Annotation信息仅存在于编译器处理期间,编译器处理完之后就没有该Annotation信息了 */
CLASS, /* 编译器将Annotation存储于类对应的.class文件中。默认行为 */
RUNTIME /* 编译器将Annotation存储于class文件中,并且可由JVM读入 */
}
SOURCE < CLASS < RUNTIME
public class Test01 {
//注解可以显示赋值,若没默认值,必须给注解赋值
@MyAnnotation1(name="张三",school = {"大学","参数"})
public void test1(){}
@MyAnnotation2("java") //可省略value=
public void test2(){}
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation1{
//注解的参数 : 参数类型 + 参数名();
String name();
String sex() default "";
int age() default 0;//给出默认值
String[] school();
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
String value();//只有一个参数默认用value进行命名
}
反射
1.Reflection是Java被视为动态语言的关键,可获得任何类的内部信息,并能直接操作任意对象的内部属性及方法。(private修饰的属性可操作)
正常方式:引入需要的"包类"名称——>通过new实例化——>取得实例化对象
反射方式:实例化对象——>getClass()方法——>得到完整的"包类"名称
一个类在内存中只有一个Class对象,一个类被加载后,类的整个结构都会被封装在Class对象中。
类继承Object类可获得getClass()方法
(1)Class类的创建方式
class Person {//父类
public String name;
public Person() { }
public Person(String name) {
this.name = name;
}
}
class Student extends Person {//子类
public Student() {
this.name = "学生";
}
}
public class RefleTest01 {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
System.out.println("这个人是:" + person.name);//这个人是:学生
//方式1:通过对象获得
Class c1 = person.getClass();
System.out.println(c1.hashCode());//2129789493
//方式2:forName获得
Class c2 = Class.forName("java_basics.Annotations.Student");
System.out.println(c2.hashCode());//2129789493
//方式3:通过类名.class获得
Class c3 = Student.class;
System.out.println(c3.hashCode());//2129789493
//方式4:基本内置类型的包装类都有一个Type属性
Class c4 = Integer.TYPE;
System.out.println(c4);//int
//获取父类类型
Class c5 = c1.getSuperclass();
System.out.println(c5);//class java_basics.Annotations.Person
}
}
(2)哪些类型可以有Class对象
只要元素类型与维度一样,就是同一个Class。
Class cl1 = Object.class; //类.class
Class cl2 = Comparable.class;//接口.class
Class cl3 = String[].class; //一维数组.class
Class cl4 = int[][].class; //二维数组.class
Class cl5 = Override.class; //注解.class
Class cl6 = ElementType.class;//枚举类型.class
Class cl7 = Integer.class;//基本数据类型.class
Class cl8 = void.class;//空类型
Class cl9 = Class.class; //Class
System.out.println(cl1 ); //class java.lang.Object
System.out.println(cl2 ); //interface java.lang.Comparable
System.out.println(cl3 ); //class [Ljava.lang.String;
System.out.println(cl4 ); //class [[I
System.out.println(cl5 ); //interface java.lang.Override
System.out.println(cl6 ); //class java.lang.annotation.ElementType
System.out.println(cl7 ); //class java.lang.Integer
System.out.println(cl8 ); //void
System.out.println(cl9 ); //class java.lang.Class
2. Java内存分析
3. 获得类的信息
Class c1 = Class.forName("java_basics.Extends_test.Person");
/*Person p=new Person();
c1 = p.getClass();*/
//获得类的名字
System.out.println("c1.getName() = "+c1.getName()); //包名+类名
System.out.println("c1.getSimpleName() = " + c1.getSimpleName()); //类名
//获得类的属性
Field[] fields = c1.getFields();//只能找到public属性
for (Field field : fields) {
System.out.println(field);
}
Field[] declaredFields = c1.getDeclaredFields();//可以找到全部属性
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
//获得指定属性
Field de = c1.getDeclaredField(String.valueOf("score"));
Field fi = c1.getDeclaredField("name");
System.out.println(fi);
System.out.println(de);
//获得类的方法
Method[] methods = c1.getMethods();
for (Method method : methods) {
System.out.println("正常的"+method);//获得本类及其父类的全部public方法
}
methods = c1.getDeclaredMethods();
for (Method method : methods) {
System.out.println(" "+method); //获得本来的所有方法
}
//获得指定的方法
Method getName = c1.getMethod("getName", null);
Method setName = c1.getMethod("setName", String.class);
System.out.println("getName = " + getName);
System.out.println("setName = " + setName);
//获得构造器
Constructor[] constructors = c1.getConstructors();//获得public构造器
Constructor[] declaredConstructors = c1.getDeclaredConstructors(); //获得全部的构造器
//获得指定的构造器
Constructor deCons = c1.getDeclaredConstructor(double.class, String.class, int.class);
System.out.println(deCons);
4. 反射(使用Class对象的newInstance()方法)创建类的对象
public class RefleTest03 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
//获得class对象
Class c1 = Class.forName("java_basics.Annotations.User");
//构造一个对象
User user = (User) c1.getDeclaredConstructor().newInstance();//本质上是调用了无参构造器
System.out.println(user); //User{name='null', age=0, id=0}
//通过构造器创建对象
Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
User user1 = (User) constructor.newInstance("张三", 15, 20220628);
System.out.println("user1 = " + user1); //user1 = User{name='张三', age=15, id=20220628}
//通过反射调用普通方法
User user2 = (User) c1.getDeclaredConstructor().newInstance();
//通过反射获取一个方法
Method setName = c1.getDeclaredMethod("setName", String.class);
//invoke:激活 (对象,“方法的值”)
setName.invoke(user2,"李四");
System.out.println("user2.getName() = " + user2.getName());//user2.getName() = 李四
//通过反射操作属性
User user3 = (User) c1.getDeclaredConstructor().newInstance();
Field name = c1.getDeclaredField("name");
//不能直接操作私有属性,需要关闭程序的安全检测,属性/方法.setAccessible(true);
name.setAccessible(true);
name.set(user3,"王五");
System.out.println("user3.getName() = " + user3.getName()); //user3.getName() = 王五
}
}
通过反射获取泛型
//通过反射获取泛型
public class RefleTest04 {
public void test01(Map<String,User> map, List<User> list){
System.out.println("test01");
}
public Map<String,User> test02(){
System.out.println("test02");
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Method method = RefleTest04.class.getMethod("test01", Map.class, List.class);
Type[] genericParameterTypes = method.getGenericParameterTypes();//获得泛型的参数信息
for (Type genericParameterType : genericParameterTypes) {
System.out.println("genericParameterTypes = " + genericParameterTypes);
//知道参数类型中的类型
if(genericParameterType instanceof ParameterizedType){ //是否是参数化类型
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();//获得真实参数类型
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println("actualTypeArgument = " + actualTypeArgument);
}
}
}
method = RefleTest04.class.getMethod("test02",null);
Type genericReturnType = method.getGenericReturnType();//获取返回值类型
if(genericReturnType instanceof ParameterizedType){ //是否是参数化类型
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();//获得真实参数类型
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println("actualTypeArgument = " + actualTypeArgument);
}
}
}
}
5. 反射操作注解
利用注解和反射完成类和表结构的映射关系
//对类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableName{
String value();
}
//对属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldName{
String columnName();
String type();
int length();
}
//定义类
@TableName("db_student")
class Students{
@FieldName(columnName = "db_id",type ="int",length = 8)
private int id;
@FieldName(columnName = "db_name",type ="varchar",length = 3)
private String name;
@FieldName(columnName = "db_age",type ="int",length = 2)
private int age;
public Students() {
}
public Students(int id,String name,int age){
this.id=id;
this.name=name;
this.age=age;
}
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;
}
@Override
public String toString() {
return "Students{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class RefleTest05{
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("java_basics.Annotations.Students");
//通过反射获得注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);//@java_basics.Annotations.TableName(value="db_student")
}
//获得注解的value的值
TableName tableName = (TableName)c1.getAnnotation(TableName.class);//获取指定的注解
System.out.println("tableName.value() = " + tableName.value());//tableName.value() = db_student
//获取类指定的注解
Field f = c1.getDeclaredField("name");//获得属性
FieldName annotation = f.getAnnotation(FieldName.class);//获得属性的注解
System.out.println("annotation.columnName() = " + annotation.columnName());//annotation.columnName() = db_name
System.out.println("annotation.type() = " + annotation.type());//annotation.type() = varchar
System.out.println("annotation.length() = " + annotation.length());//annotation.length() = 3
}
}
标签:Java,20220628,System,public,学习,println,c1,class,out 来源: https://www.cnblogs.com/Joyce-mi7/p/16418837.html