【爆炒洋葱圈】 Java知识点 对象、类、继承、反射

上一篇请见:https://blog.csdn.net/csc1998/article/details/88263233
本文章中,反射的内容并不是太详尽。由于时间有限,没有来得及完全读透


对象与类

  • java总是采用按值调用(call by value)。也就是说,方法得到的是所有参数值的一个拷贝。方法不能修改传递给他的任何参数变量的内容。
  • 一个方法不可能修改一个基本数据类型的参数。但是在传入对象引用时,由于得到的是一个对象引用的拷贝,对象引用及其拷贝指向同一个对象,所以可以很容易地更改对象的值。
  • 由于java是按值调用,所以没有办法使用函数来交换两个引用所指向的对象
  • 类中的构造器中语句的第一行如果形如this(…)则是调用其他构造器
  • 初始化块在类中直接用{}扩起来,只要构造类的对象,初始化块就会被执行。初始化块可以有多个
  • 初始化块➡构造器主体部分
  • 静态域初始化块:在类中直接用static{}括起来,可以初始化比较复杂的静态域
  • 想要对包进行注释,那么就要在每一个包目录中添加一个单独的文件

继承

  • 超类不是超级类,指的是父类,基类,是一个更加广泛、更加普遍适用的类。而子类则是超类的子集,是“更具个性化的”、功能更加细致和丰富的类。公共方法应该放在超类中,而特殊方法应该放在子类中
  • 注意:在构造器中的this(…)和super(…)的具体含义是调用自身的另一个构造器/调用超类的构造器,都只能在构造器的第一条语句中出现
  • 可以将一个子类的引用赋给超类变量。因为这样只会新增一些方法和域,超类的方法一定会出现在子类中。而不能将一个超类的引用赋给子类变量。因为如果这么做的话,会导致子类中特有的一些方法和域丢失,进而导致在方法调用的时候出现运行时错误
  • 如果将一个类声明为final,只有其中的方法自动成为final,而不包括域
  • 在将超类强制转换成子类时,应该使用instanceof进行检查,以防产生ClassCastException异常。而一般情况建议减少类型转换和instanceof
  • 注意:与C++不同,protected对子类以及同一个包中的所有其他类都可见,而不是只对子类可见
  • Object.equals()比较两个对象是否具有相同引用,如果需要其他的相等方法,则需要重写equals方法
  • 字符串的散列码(hashCode)是由字符串导出的
  • ArrayList.ensureCapacity(int n)或new ArrayList(int n)可以扩充列表底层数组的值。具体见ArrayList中ensureCapacity的使用与优化。与数组new int[100]不同,数组新建是有100个空位置可以使用,而链表只是有保存100个元素的潜力。
  • ArrayList.trimToSize(int n)将存储区域的大小调整为当前元素所需要的存储空间数目,多余空间被GC回收
  • ArrayList的下标也是从0开始
  • ArrayList不允许是基本类型,但是可以是基本类型的包装器
  • 基本类型的包装器具有自动装箱和拆箱功能。所以对于包装器,可以采取与基本类型类似的运算方法,包括=、+、-、*、/
  • 包装类的数值是不可以改变的,与String相同。用=重新赋值会更改指向包装类的引用,使其指向新的包装类
  • 关于String s = new String(“a”):至少创建一个对象,至多创建两个对象。首先在string池中搜索"a"字符串是否存在,不存在则创建,存在则将它的引用赋值给s;遇到new,创建新对象,并将引用赋给s
  • 包装器的==为比较引用(所有非基本类型都是如此)。如果要比较值相等,使用equals()
  • 自动装箱规范要求boolean/byte/char≤127、介于-128~127的short和int被包装到固定的对象中。也就是说如果符合上述条件,相同数值的包装器实例使用==比较结果一定为真
  • 参数数量可变:在方法定义中,参数中形如Object…中的省略号表示可以接受任意数量的对象

枚举类

例子:

public enum Size{ SMALL, MEDIUM, LARGE, EXTRA_LARGE };

实际上,这个声明定义的类型是一个类,它刚好有四个实例,在此尽量不要构造新对象。
因此,在比较两个枚举类型的值时,永远不需要调用equals方法,而直接使用"=="就可以了。(equals()方法也是直接使用 ==, 两者是一样的效果)

如果有需要,可以在枚举类中添加方法

public enum Mode {
    PULLDOWN("下拉"), PULLUP("上拉");
    private final String value;

    Size(String value) {
        this.value = value;
    }
    
    public String getValue() {
        return value;
    }
}

以上图为例。在初始化此枚举类型时,将会自动使用类的构造器(只能为private)构造两个实例,并且在整个生命周期,也只有这两个实例。并且在其他代码内,不能创建enum实例。
ordinal方法返回enum声明中枚举常量的位置,位置从0开始。

反射

反射的功能极其强大,他可以用来:

  • 在运行时分析类的能力
  • 在运行时查看对象,例如,编写一个toString方法供所有类使用
  • 实现通用的数组代码
  • 利用Method对象,这个对象很像C++中的函数指针

Class类

Java运行时为每个对象维护一个被称为运行时的类型标识,这个信息跟踪着每个对象所属的类。虚拟机利用运行时类型信息选择相应的方法执行。

Class类就是专门访问这些信息的类。Object.getClass将会返回一个Class实例。

  • Class.getName() 获取类的名字,包名也包含其中
  • Class.forName() 静态方法,获取类名对应的Class对象
  • Class.newInstance() 可以动态创建一个实例。注意:创建的实例所对应的类一定要有无参构造器才可以调用newInstance()(自定义的有参构造器会覆盖无参构造器,如果有有参构造器存在,务必要重写一个无参构造器),否则会报实例化异常InstantiationException

JVM为每个类型管理一个Class对象。因此,可以利用 == 运算符实现两个类对象比较。if(e.getClass() == Employee.class)注意两个返回的都是一个Class对象

Class类中

  • Field[] getFields()
  • Method[] getMethods()
  • Constructor[] getCOnstructors()

只会返回这个类或者其超类的公有部分(域、方法、构造器)

若想获得所有部分(域、方法、构造器),使用形如getDeclaredFields()的函数

在Field/Method/Constructor中,getModifiers()返回一个描述构造器、方法或域的修饰符的整形数值。可以调用Modifier类中的静态方法去判断修饰符的情况。例如:Modifier.isPrivate(con.getModifiers())

为了安全,反射对对象的值的访问默认也受权限修饰符的制约。Java安全机制在默认情况只允许任意对象有哪些域,而不能读出不具有读取权限的域的值。

然而,可以通过setAccessible()来修改上述对象的访问控制

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值