前两天都有点高强度了,所以这个隔了好一段时间缓一缓,今天写的也比较短,另外我本身有自己的工作,所以都是业余时间学习,所以更新笔记时间就更加不确定了,并不是全天都在学这个东西.写的比较菜比较片面,也希望大佬们温柔对待.
Java认为一切都是对象,每个都想都能归到某个类,所以,我们也可以获得这个对象对应的类.
public class basic {
public static void main(String[] args) {
Class classFromClass = Fruit.class;
System.out.println(classFromClass.getName());
Fruit fruit1 = new Fruit("苹果","red", 10.0,10.0);
Class classFromFruit1 = fruit1.getClass();
System.out.println(classFromFruit1.getName());
}
}
输出结果
com.world.hello.Fruit
com.world.hello.Fruit
Class类也有一些常见的方法.
- equals - 判断当前类和目标类是不是类型相等
- getDeclaredMethods - 获取当前类已声明的所有方法
- getDeclaredMethod - 获取当前类已声明的指定方法
- getDeclaredFields - 获取当前类已声明的所有字段
- getDeclaredField - 获取当前类已声明的指定方法
- getName - 获取完整类名
- getSimpleName - 获取类名
- getPackage - 获取类所在包名
- getSuperclass - 获取父类类型
可以利用反射技术操作私有属性,这个操作并不使用对象的setXXX方法,即哪怕setXXX是私有或者根本没实现,都可以操作.
public static void main(String[] args) {
Fruit fruit = new Fruit("苹果","red", 10.0,10.0);
try{
Class clazz = fruit.getClass();
Field price = clazz.getDeclaredField("price");
// 看看是不是成功获得了!如果不成功就到异常不往下了.
try{
price.setAccessible(true);
price.set(fruit, 50.0);
System.out.println(fruit.getPrice());
}catch(IllegalAccessError | IllegalAccessException e){
e.printStackTrace();
}
}catch (NoSuchFieldException | SecurityException e){
e.printStackTrace();
}
}
首先获得了这个类的Class对象,然后设置price这个Field不为private,然后通过Filed的set方法就可以修改他,上面代码执行后就会显示苹果价格是50.0.
对于私有方法也可以使用类似的方法.
public static void main(String[] args) {
Fruit fruit = new Fruit("苹果","red", 10.0,10.0);
try{
Class clazz = fruit.getClass();
Method method = clazz.getDeclaredMethod("setPrice",Double.class);
// 看看是不是成功获得了!如果不成功就到异常不往下了.
try{
method.setAccessible(true);
method.invoke(fruit,50.0);
System.out.println(fruit.getPrice());
}catch(IllegalAccessError | IllegalAccessException | InvocationTargetException e){
e.printStackTrace();
}
}catch (NoSuchMethodException | SecurityException e){
e.printStackTrace();
}
}
不过由于Class能包裹的实在太多了,所以还要按照泛型一样给他修饰才算比较科学.
Class<? extends Fruit> clazz = fruit.getClass();
我们一直写代码中,IDEA偶尔会给我们添加一些特殊的字,比如@Override,这些不是注释,是注解,注解是给开发过程/运行过程检查使用的.前面说的Override就是代表此处从写了父类的方法,有些方法我们写的时候就提示废弃了,也是被注解了.
我们给一个不使用的函数添加一个注解,抑制未使用警告.
@SuppressWarnings("unused")
public static void notUsed(){
System.out.println("Hello World");
}
这样在IDEA就不报告警告了.
这些注解也是人规定的,我们随便打开Documented这个注解,发现他内容是这样的.
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
其中@Documented这个注解一旦存在,会被javadoc提取成文档,@Target表明注解的类型,可以是TYPE(类,接口,枚举),FIELD,METHOD(方法但不含构造方法),PARAMETER(方法的参数),CONSTRUCTOR(构造方法),LOCAL_VARIABLE(局部变量),ANNOTATION_TYPE(注解类型),PACKAGE(包),@Retention注明这个注解保留策略,SOURCE代表整个注解只在编码阶段保留,CLASS表示保留至CLASS文件,RUNTIME表示运行时依然能检测到他.
通过反射机制的可以知道有没有包含某个注解,注解也可以自行添加,比如这一句检查一下我刚提取的method有没有包含Documented的注解,自己写的注解也可以用,并不是只有系统内置注解.
method.isAnnotationPresent(Documented.class);
到这里,Java的基础知识应该就建立了,后面开始搞各种现成的轮子,至于自己做轮子,那完全就是看自己具体能力了.