Java学习_20220628
2022/6/29 14:23:18
本文主要是介绍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的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-09聊聊如何通过arthas-tunnel-server来远程管理所有需要arthas监控的应用
- 2024-05-09log4j2这么配就对了
- 2024-05-09nginx修改Content-Type
- 2024-05-09Redis多数据源,看这篇就够了
- 2024-05-09Google Chrome驱动程序 124.0.6367.62(正式版本)去哪下载?
- 2024-05-09有没有大佬知道这种数据应该怎么抓取呀?
- 2024-05-09这种运行结果里的10.100000001,怎么能最快改成10.1?
- 2024-05-09企业src漏洞挖掘-有意思的命令执行
- 2024-05-08阿里云域名注册流程,分享给第一次购买域名的新手站长!
- 2024-05-082024年,行业变动下的程序员应该首先学习哪种编程语言?