精华内容
下载资源
问答
  • 我不是问Java的参数传递如何工作的.我知道看起来像一个持有对象的变量实际上一个包含对象的引用的变量,该引用通过值传递的.在这里(在链接的线程和其他)以及其他地方,有很多关于该机制的精细解释.问题关于...

    谁有权决定?

    编辑:显然我没有成功地制定好我的问题.

    我不是问Java的参数传递是如何工作的.我知道看起来像一个持有对象的变量实际上是一个包含对象的引用的变量,该引用是通过值传递的.

    在这里(在链接的线程和其他)以及其他地方,有很多关于该机制的精细解释.

    问题是关于术语“通过参考”的技术含义. (完成编辑)

    我不知道这是否是SO的正确的问题,如果不是,道歉,但我不知道一个更好的地方.在其他问题上已经有很多话已经说过了,例如Is Java pass by reference?和pass by reference or pass by value?,但是我没有在这个问题上找到一个权威性的答案.

    我认为“通过引用”是指“通过一个引用(通常是一个指针)到对象”,所以被调用者可以修改调用者看到的对象,而“通过值”意味着复制对象,并让被叫方有复制的乐趣(明显的问题:如果对象包含引用,深层复制或浅色).

    唱FW开始lots of places saying“通过引用”意思就是这样,here有一些说法意味着更多,但是定义仍然读

    A ParameterPassing mode where a reference (or if you want to be politically incorrect, a pointer) to the actual parameter is passed into the formal parameter; when the callee needs the formal parameter it dereferences the pointer to get it.

    我没有找到很多地方给出更强的定义,在this页,我发现“形式参数的左值设置为实际参数的左值”.并且如果我理解正确,则使用相同的定义here(“形式参数仅仅作为实际参数的别名”.)

    事实上,唯一发现使用更强的定义的地方是反对在Java中的对象被引用传递(这可能是由于我缺少google-fu)的概念的地方.

    所以,如果我有事情直接,通过参考

    class Thing { ... }

    void byReference(Thing object){ ... }

    Thing something;

    byReference(something);

    根据第一个定义大致对应(在C中)

    struct RawThing { ... };

    typedef RawThing *Thing;

    void byReference(Thing object){

    // do something

    }

    // ...

    struct RawThing whatever = blah();

    Thing something = &whatever;

    byReference(something); // pass whatever by reference

    // we can change the value of what something (the reference to whatever) points to, but not

    // where something points to

    在这个意义上说,Java通过引用传递对象就足够了.但是根据第二个定义,传递参考意味着或多或少

    struct RawThing { ... };

    typedef RawThing *RawThingPtr;

    typedef RawThingPtr *Thing;

    void byReference(Thing object){

    // do something

    }

    // ...

    RawThing whatever = blah();

    RawThingPtr thing_pointer = &whatever;

    byReference(&thing_pointer); // pass whatever by reference

    // now we can not only change the pointed-to (referred) value,

    // but also where thing_pointer points to

    而且由于Java只允许你有指针对象(限制你可以使用的对象),但是没有指针指针,在这个意义上说,Java通过引用传递对象是完全错误的.

    所以,

    >我是否充分了解上述传递参考的定义?

    >周围有其他定义吗?

    >有共识哪个定义是“正确的”,如果是,哪个?

    展开全文
  • 它的具体用途是什么?你觉得它是以什么样的方式排列的?你不能在里面储存东西,你不能从里面取出东西,它不包含任何东西…基本上,它没有通常与数组关联的属性。链接到我的另一个答案,一些人发现这是有用的。我知道...

    本问题已经有最佳答案,请猛点这里访问。

    所以我研究了这个"枚举"类型,在我看来它有点像一个美化的数组/ArrayList/List。它的具体用途是什么?

    你觉得它是以什么样的方式排列的?你不能在里面储存东西,你不能从里面取出东西,它不包含任何东西…基本上,它没有通常与数组关联的属性。

    链接到我的另一个答案,一些人发现这是有用的。我知道这是一个比较Java枚举和C++枚举的线程,但是我试着在那里描述JavaEnUM属性。

    @啊,我想我明白了:源代码中的定义有点像列表文字…

    枚举不是数组,但如果您的枚举是myenum,则myenum.values()是枚举中所有常量的数组

    如果类应该具有固定的可枚举实例数,则使用enum而不是class。

    实例:

    DayOfWeek=7个实例→enum

    CardSuit=4个实例→enum。

    Singleton=1个实例→enum

    >

    Product=可变实例数→class。

    User=可变实例数→class。

    Date=可变实例数→class。

    也用于诸如应用程序中的语言切换之类的东西,例如菜单名等

    是的,当选项在编译时已知时:)

    是的,当然。只需添加一个示例:p

    当类的实例具有非常相似或可注入的行为模式时;必须切换事例时,枚举自身方法中的类事例可能是一种代码味道。

    枚举作为固定数量的常量的一种类型,至少可以用于两个方面

    常数

    public enum Month {

    JANUARY, FEBRUARY, ...

    }

    这比创建一组整型常量要好得多。

    创建单例

    public enum Singleton {

    INSTANCE

    // init

    };

    你可以用Enums做一些有趣的事情,看这里

    还要看官方文件

    这两件事几乎是一样的。单子也是一个常数,不是吗?

    @看看这个informit.com/articles/article.aspx?p=1216151&seqnum=3

    @当然,它向您展示了如何将枚举用作单例。第一个例子(常量)是一个固定的常量列表。另一方面,这一行为更像是一个普通类,但是Java本身确保这个类只创建一次。

    啊,但是你也可以反过来用两个参数:一个是一个固定的常数列表,EDCOX1的0个EnEnm就像一个普通类,除了Java保证这个类只被实例化了12次。你说"至少可以用两样东西",我说这两样东西是一样的。:-)你不同意吗?

    @aioobe否。singleton不是一个固定的常量列表。singleton意味着一个特定的对象只被实例化一次。情况完全不同。我想你错过了重点。

    @托马斯,我不认为单件使用是"完全不同的"。程序员的意图可能不同,因为单例在应用程序中通常扮演更大的角色,而多值枚举通常是一些小的特定细节。也许这就是你的评论的目的。但是从技术上讲,singleton枚举只是一个"固定的常量列表",它只包含一个元素。正如Aiobe所问,从技术上讲,这个答案中的两个例子完全相同;一个是具有12个值的枚举,另一个是具有1个值的枚举。

    枚举类型基本上是一种数据类型,它允许您以更可读和可靠的方式描述类型的每个成员。

    下面是一个简单的例子来解释为什么:

    假设你写的方法与季节有关:int枚举模式

    首先,您声明了一些int静态常量来表示每个季节。

    public static final int SPRING = 0;

    public static final int SUMMER = 1;

    public static final int FALL = 2;

    public static final int WINTER = 2;

    然后,您声明了将季节名称打印到控制台中的方法。

    public void printSeason(int seasonCode) {

    String name ="";

    if (seasonCode == SPRING) {

    name ="Spring";

    }

    else if (seasonCode == SUMMER) {

    name ="Summer";

    }

    else if (seasonCode == FALL) {

    name ="Fall";

    }

    else if (seasonCode == WINTER) {

    name ="Winter";

    }

    System.out.println("It is" + name +" now!");

    }

    所以,在那之后,你可以打印这样的季节名称。

    printSeason(SPRING);

    printSeason(WINTER);

    对于一个类中不同类型的成员,这是一种非常常见(但很糟糕)的方法来做不同的事情。但是,由于这些代码涉及整数,所以您也可以这样调用方法,而不会有任何问题。

    printSeason(0);

    printSeason(1);

    或者像这样

    printSeason(x - y);

    printSeason(10000);

    编译器不会抱怨,因为这些方法调用是有效的,并且您的printSeason方法仍然可以工作。

    但这里有点不对劲。10000的季节代码应该是什么意思?如果x - y产生负数怎么办?当您的方法接收到一个没有意义且不应该存在的输入时,您的程序对它一无所知。

    例如,您可以通过添加附加检查来解决此问题。

    ...

    else if (seasonCode == WINTER) {

    name ="Winter";

    }

    else {

    throw new IllegalArgumentException();

    }

    System.out.println(name);

    现在,当季节代码无效时,程序将抛出一个RunTimeException。但是,您仍然需要决定如何处理异常。

    顺便问一下,我确信你注意到FALL和WINTER的代码都是2,对吗?

    你现在应该明白了。这种图案很脆。它使您可以在任何地方编写条件检查。如果你正在做一个游戏,并且你想在你想象的世界里增加一个额外的赛季,这个模式会让你通过所有按赛季做事情的方法,在大多数情况下,你会忘记其中的一些。

    对于这种情况,您可能认为类继承是一个好主意。但我们只需要其中的一部分,不再需要了。

    这时,enum开始发挥作用。使用enum型

    在爪哇中,EDCOX1×12种类型是通过公共静态最终字段为每个枚举常量导出一个实例的类。

    这里可以声明四个枚举常量:SPRING, SUMMER, FALL, WINTER。每个都有自己的name。

    public enum Season {

    SPRING("Spring"), SUMMER("Summer"), FALL("Fall"), WINTER("Winter");

    private String name;

    Season(String name) {

    this.name = name;

    }

    public String getName() {

    return name;

    }

    }

    现在,回到方法上来。

    public void printSeason(Season season) {

    System.out.println("It is" + season.getName() +" now!");

    }

    现在可以使用Season作为输入,而不是使用int。你可以告诉Season给你名字,而不是条件检查。

    这就是您现在如何使用此方法:

    printSeason(Season.SPRING);

    printSeason(Season.WINTER);

    printSeason(Season.WHATEVER);

    当您使用不正确的输入时,您将得到一个编译时错误,并且只要程序编译,您就保证获得Season的非空单例引用。

    当我们需要一个额外的季节时,我们只需在Season中添加另一个常量,而不再添加。

    public enum Season {

    SPRING("Spring"), SUMMER("Summer"), FALL("Fall"), WINTER("Winter"),

    MYSEASON("My Season");

    ...

    每当需要一组固定的常量时,enum是一个不错的选择(但并非总是如此)。它是一个更可读、更可靠、更强大的解决方案。

    枚举类型是其字段由一组固定常量组成的类型。常见的例子包括指南针方向(北、南、东和西的值)和星期几。

    public enum Day {

    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,

    THURSDAY, FRIDAY, SATURDAY

    }

    每当需要表示一组固定的常量时,都应该使用枚举类型。这包括自然枚举类型,例如太阳系中的行星和数据集,其中您在编译时知道所有可能的值,例如菜单上的选项、命令行标志等等。

    下面是一些代码,演示如何使用上面定义的day枚举:

    public class EnumTest {

    Day day;

    public EnumTest(Day day) {

    this.day = day;

    }

    public void tellItLikeItIs() {

    switch (day) {

    case MONDAY:

    System.out.println("Mondays are bad.");

    break;

    case FRIDAY:

    System.out.println("Fridays are better.");

    break;

    case SATURDAY: case SUNDAY:

    System.out.println("Weekends are best.");

    break;

    default:

    System.out.println("Midweek days are so-so.");

    break;

    }

    }

    public static void main(String[] args) {

    EnumTest firstDay = new EnumTest(Day.MONDAY);

    firstDay.tellItLikeItIs();

    EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);

    thirdDay.tellItLikeItIs();

    EnumTest fifthDay = new EnumTest(Day.FRIDAY);

    fifthDay.tellItLikeItIs();

    EnumTest sixthDay = new EnumTest(Day.SATURDAY);

    sixthDay.tellItLikeItIs();

    EnumTest seventhDay = new EnumTest(Day.SUNDAY);

    seventhDay.tellItLikeItIs();

    }

    }

    输出是:

    Mondays are bad. Midweek days are so-so. Fridays are

    better. Weekends are best. Weekends are best.

    Java编程语言枚举类型比其他语言中的同类语言要强大得多。枚举声明定义一个类(称为枚举类型)。枚举类主体可以包括方法和其他字段。编译器在创建枚举时自动添加一些特殊方法。例如,它们有一个静态值方法,该方法返回一个数组,该数组按照声明的顺序包含枚举的所有值。此方法通常与for each构造结合使用,以迭代枚举类型的值。例如,下面这个行星类例子中的代码迭代了太阳系中的所有行星。

    for (Planet p : Planet.values()) {

    System.out.printf("Your weight on %s is %f%n",

    p, p.surfaceWeight(mass));

    }

    除了其属性和构造,Planet还有一些方法可以让您检索每个行星上物体的表面重力和重量。下面是一个样本程序,它可以计算你在地球上的重量(以任何单位表示),并计算和打印你在所有行星上的重量(以相同单位表示):

    public enum Planet {

    MERCURY (3.303e+23, 2.4397e6),

    VENUS   (4.869e+24, 6.0518e6),

    EARTH   (5.976e+24, 6.37814e6),

    MARS    (6.421e+23, 3.3972e6),

    JUPITER (1.9e+27,   7.1492e7),

    SATURN  (5.688e+26, 6.0268e7),

    URANUS  (8.686e+25, 2.5559e7),

    NEPTUNE (1.024e+26, 2.4746e7);

    private final double mass;   // in kilograms

    private final double radius; // in meters

    Planet(double mass, double radius) {

    this.mass = mass;

    this.radius = radius;

    }

    private double mass() { return mass; }

    private double radius() { return radius; }

    // universal gravitational constant  (m3 kg-1 s-2)

    public static final double G = 6.67300E-11;

    double surfaceGravity() {

    return G * mass / (radius * radius);

    }

    double surfaceWeight(double otherMass) {

    return otherMass * surfaceGravity();

    }

    public static void main(String[] args) {

    if (args.length != 1) {

    System.err.println("Usage: java Planet ");

    System.exit(-1);

    }

    double earthWeight = Double.parseDouble(args[0]);

    double mass = earthWeight/EARTH.surfaceGravity();

    for (Planet p : Planet.values())

    System.out.printf("Your weight on %s is %f%n",

    p, p.surfaceWeight(mass));

    }

    }

    如果从命令行运行planet.class,参数为175,则会得到以下输出:

    $ java Planet 175 Your weight on MERCURY is 66.107583 Your

    weight on VENUS is 158.374842 Your weight on EARTH is

    175.000000 Your weight on MARS is 66.279007 Your weight on JUPITER is 442.847567 Your weight on SATURN is 186.552719 Your

    weight on URANUS is 158.397260 Your weight on NEPTUNE is

    199.207413

    来源:http://docs.oracle.com/javase/tutorial/java/javaoo/enum.html

    您至少可以编写一个源代码,因为您复制粘贴的官方文档没有任何更改。

    冷静点,伙计们,我只不过是在帮他而已!源链接现已附加!!!!!!!

    老实说,那篇文章以一个相当误导性的陈述开头。枚举可以有多个字段,而不仅仅是一组常量。

    是的,你是对的,可能是这样,但如果你继续阅读,你会发现更多关于枚举的描述,可以在细节上澄清它的使用。

    枚举是安全类型,因此不能在运行时分配新值。此外,还可以在switch语句中使用它(比如int)。

    我不知道这个答案。普通类也是类型安全的。如果您将它与使用整数进行比较,那么为什么要强调这样一个事实:您可以在开关中使用整数?!

    在开关中使用枚举比使用整数更优雅。

    你为什么这么说?(我想说,使用枚举比使用int更优雅,而且不必牺牲switch语句。)

    开关(I)…案例11:delete();break;…}切换(动作)…案例删除:delete();break;…}哪个代码最干净?枚举,不是吗?

    您不使用命名常量吗,比如在代码中使用public static in t delete=11?(对于这样做的人,switch语句看起来与枚举语句中的语句相同。)

    如果您在开关中使用了枚举,那么您做的是错误的——颠倒它,使代码在枚举中。枚举.dothings(stuff)比switch(enum)case thing1:case thing2:-更容易读取和测试代码,它还降低了循环复杂性。

    Java编程语言enums比其他语言中的其他语言要强大得多,它们只不过是美化了的整数。新的枚举声明定义了一个完整的类(称为枚举类型)。除了解决所有问题(EDOCX1,1),还存在着在Java 5之前使用的以下int模式:

    public static final int SEASON_WINTER = 0;

    它还允许您向枚举类型添加任意方法和字段,实现任意接口等等。枚举类型提供所有对象方法的高质量实现。它们是Comparable和Serializable,串行形式设计为能够承受枚举类型的任意更改。您也可以在switch案例中使用enum。

    阅读关于Java枚举HTTP://DOCS.Oracle .COM/JavaSe/1.5.0/DOCS/GuID/Laule/No.StHTML的完整文章以获取更多细节。

    但有时我只想要一组带光泽的整数

    枚举是为一组已定义的容器(也可以有一些有限的行为)提供易于记忆的名称的推荐方法。

    在使用多个静态整型常量(如public static int ROLE_ADMIN = 0或BLOOD_TYPE_AB = 2时,应使用枚举。

    使用枚举而不是这些枚举的主要优点是类型安全、在尝试使用错误值时编译类型警告/错误以及为相关的"常量"提供命名空间。此外,它们更容易在IDE中使用,因为它也有助于代码完成。

    1)枚举是面向对象方法中的关键字。

    2)它是用来把代码写在一行中的,也就是说不超过这一行。

    public class NAME

    {

    public static final String THUNNE ="";

    public static final String SHAATA ="";

    public static final String THULLU ="";

    }

    -------This can be replaced by--------

    enum NAME{THUNNE, SHAATA, THULLU}

    3)大多数开发人员不使用枚举关键字,它只是一种替代方法。

    滑稽的回答:

    展开全文
  • (咱们在分析一个技术的时候,先要考虑它是想解决什么问题,或者学习新知识的时候,要清楚这个知识的目的是什么)。我在编译内核的时候,发现arch/arm/kernel目录下有一个这样的文 件:vmlinux.lds.S。第一眼看上去,...

    先要讲讲这个问题是怎么来的。(咱们在分析一个技术的时候,先要考虑它是想解决什么问题,或者学习新知识的时候,要清楚这个知识的目的是什么)。

    我在编译内核的时候,发现arch/arm/kernel目录下有一个这样的文 件:vmlinux.lds.S。第一眼看上去,想想是不是汇编文件呢?打开一看,好像不是。那它是干嘛的?而且前面已经说过,make V=1的时候,发现这个文件的用处在ld命令中,即ld -T vmlinux.lds.S,好像是链接命令用的,如下所示

    如arm-linux-ld -EL -p --no-undefined -X --build-id -o vmlinux -T arch/arm/kernel/vmlinux.lds。man ld,得到-T的意思是:为ld指定一个Linker script,意思是ld根据这个文件的内容来生成最终的二进制。

    也许上面这个问题,你从没关注过,但是在研究内核代码的时候,常常有地方说“ __init宏会在最后的模块中生成一个特定的section,然后kernel加载的时候,寻找这个section中的函数”,说白了,上面这句话就是 说最后生成的模块中,有一个特定的section,这又是什么东西?

    好吧,希望上面的问题勾起你的好奇心。下面我们来扫盲,最后会给一个链接地址,各看官可以去那深造。

    一 section是什么?

    好吧,我们需要解释一下平时编译链接生成的二进制可执行程序(比如说ELF,EXE也行),so或者dll,内核(非压缩的,参加本系列第一节内容、vmlinux),或者ko是怎么组织的。

    其实,大家或多或少都知道这些二进制中包括有什么text/bss/data节(也叫section)。text节存储的是代码、data存储的是已经初始化的静态变量、bss节存储的是未初始化的什么东西...

    上面的东西我就不细究了。反正一点,一个二进制,最终会包含很多section。那么,为什么section叫text/bss/data,能叫别的名字吗?

    OK,可以。但是你得告诉ld,那么这些内容就通过-T选项指定一个linker script就行了。这些内容我们放到后面的实例中来介绍。

    (再三强调,咱们在理论上只是抛砖引玉,希望有兴趣的看官自己研究,注意和我们分享你的成果就行了。)

    二 link script基础知识介绍

    linker script中的语法是linker command language(很简单的language,大家不用害怕...)。那么LS的目的是什么呢?

    LS描述输入文件(也就是gcc -c命令产生的.o文件即object文件)中的section最终如何对应到一个输出文件。这个其实好理解,例如一个elf由三个.o文件构成,每 个.o文件都有text/data/bss段,但最终的那一个elf就会将三个输入的.o文件的段合并到一起。

    好了,下面我们介绍一些基本知识:

    ld的功能是将input文件组装成一个output文件。这些文件内部的都有特殊 的组织结构,这种结构被叫做object file format。每一个文件叫做object file(这可能就是.o文件的来历吧。哈哈),输出文件也叫可执行文件(an executable),但是对于ld来说,它也是一种object文件。那么Object文件有什么特殊的地方呢?恩,它内部组织是按照 section(段、或者节,以后不再区分二者)来组织的。一句话,object文件内部包含段......

    每个段都有名字和size。另外,段内部还包含一些数据, 这些数据叫做section contents,以后称段内容。每个段有不同的属性。例如text段标志为可加载(loadable),表示该段内的contents在运行时候(当然 指输出文件执行的时候)需要加载到内存中。另外一些段中没有contents,那么这些段标示为allocatable,即需要分配一些内存(有时候这些 内存会被初始化成0,这里说的应该是BSS段。BSS段在二进制文件中没有占据空间,即磁盘上二进制文件的大小比较小,但是加载到内存后,需要为BSS段 分配内存空间。),还有一些段属于debug的,这里包含一些debug信息。

    既然需要加载到内存中,那么加载到内存的地址是什么 呢?loadable和allocable的段都有两个地址,VMA:虚拟地址,即程序运行时候的地址,例如把text段的VMA首地址设置为 0x800000000,那么运行时候的首地址就是这个了。另外还有一个LMA,即Load memory address。这个地址是section加载时的地址。晕了吧?二者有啥区别?一般情况下,VMA=LMA。但也有例外。例如设置某数据段的LMA在 ROM中(即加载的时候拷贝到ROM中),运行的时候拷贝到RAM中,这样LMA和VMA就不同了。---------》很难搞懂不是?这种方法用于初始 化一些全局变量,基于那种ROM based system。(问一个问题,run的时候,怎么根据section中的VMA进行相应设置啊??以后可能需要研究下内核中关于execve实现方面的内 容了)。关于VMA和LMA,大家通过objdump -h选项可以查看。

    三 简单例子

    下面来一个简单例子,

    SECTIONS

    {

    . = 0x10000;

    .text : { *(.text) }

    . = 0x8000000;

    .data : { *(.data) }

    .bss : { *(.bss) }

    }

    SECTIONS是LS语法中的关键command,它用来描述输出文件的内存布局。例如上例中就含text/data/bss三个部分(实际上text/data/bss才是段,但是SECTIONS这个词在LS中是一个command,希望各位看官要明白)。

    .=0x10000; 其中的.非常关键,它代表location counter(LC)。意思是.text段的开始设置在0x10000处。这个LC应该指的是LMA,但大多数情况下VMA=LMA。

    .text:{*(.text)},这个表示输出文件的.text段内容由所有输入文件(*)的.text段组成。组成顺序就是ld命令中输入文件的顺序,例如1.obj,2.obj......

    此后,由来了一个.=0x800000000;。如果没有 这个赋值的,那么LC应该等于0x10000+sizeof(text段),即LC如果不强制指定的话,它默认就是上一次的LC+中间section的长 度。还好,这里强制指定LC=0X800000000.表明后面的.data段的开始位于这个地址。

    .data和后面的.bss表示分别有输入文件的.data和.bss段构成。

    你看,我们从这个LC文件中学到了什么?

    恩,我们可以任意设置各个段的LMA值。当然,绝大部分情况,我们不需要有自己的LS来控制输出文件的内存布局。不过LK(linux kernel)可不一样了......

    四 霸王硬上弓---vmlinux.lds.S分析

    OK,有了上面的基础知识,下面我们霸王硬上弓,直接分析arch/arm/kernel/vmlinux.lds.S.虽然最终链接用的是vmlinux.lds,但是那个文件

    由vmlinux.lds.S(这是一个汇编文件)得到,

    arm-linux-gcc -E -Wp,-MD,arch/arm/kernel/.vmlinux.lds.d -nostdinc ...... -D__KERNEL__ -mlittle-endian ......

    -DTEXT_OFFSET=0x00008000 -P -C -Uarm -D__ASSEMBLY__ -o arch/arm/kernel/vmlinux.lds     arch/arm/kernel/vmlinux.lds.S

    所以,我们直接分析vmlinux.lds好了。

    /*

    一堆注释,这里就不再贴上了,另外,增加//号做为注释标识

    * Convert a physical address to a Page Frame Number and back

    */

    //OUTPUT_ARCH是LS语法中的COMMAND,用来指定输出文件的machine arch。objdump -f可查询所有支持的machine。另外

    //这些东西涉及到一种叫BFD的。各位看官可以自己搜索下BFD的内容。

    //下面这 表示输出文件基于ARM架构

    OUTPUT_ARCH(arm)

    //ENTRY也是一个command,用来设置入口点。这里表示入口点是stext 。根据LD的描述,入口点的意思就是程序运行的第一条指令。内核是一个模块,大家把他想象

    //成一个运行在硬件上的大程序就可以了。而我们的程序又是运行在内核至上的。比较下Java虚拟机以及运行在其上的Java程序吧......

    ENTRY(stext)

    //设置jiffies为jiffies_64

    jiffies = jiffies_64;

    //定义输出文件的段

    SECTIONS

    {

    //设置location count为0xc0008000,这个好理解吧?内核运行的地址全在C0000000以上

    . = 0xC0000000 + 0x00008000;

    //定义一个.text.head段,由输入文件中所有.text.head段组成

    /*

    LS语法中,关于seciton的定义如下:

    section [address] [(type)] :

    [AT(lma)] [ALIGN(section_align)]

    [SUBALIGN(subsection_align)]

    [constraint]

    {

    output-section-command

    output-section-command

    ...

    } [>region] [AT>lma_region] [:phdr :phdr ...] [=fillexp]

    其中,address为VMA,而AT命令中的为LMA。一般情况,address不会设置,所以它默认等于当前的location counter

    */

    .text.head : {

    /*这个非常关键,咱们在内核代码中经常能看到一些变量声明,例如extern int __stext,但是却找不到在哪定义的

    其实这些都是在lds文件中定义的。这里得说一下编译链接相关的小知识。咱们这知道大概即可,具体内容可以自己深入研究

    假设C代码中定义一个变量 int x = 0;那么

    1 编译器首先会分配一块内存,用来存储该变量的值

    2 编译器在程序的symbol表中,创建一项,用来存储这个变量的地址

    例如,上面的 int x = 0,就在symbol表中创建一x项,这个x项指向一块内存,sizeof(int)大小,存储的值为0。当有地方使用这个x的时候,编译器会生成相应的代码,

    首先指向这个x的内存,然后读取内存中的值。

    上面的内容是C中一个变量的定义。但是Linker script中也可以定义变量,这时候只会生成一个symbol项,但是没有分配内存。。例如_stext=0x100,那么会

    创建一个symbol项,指向0x100的内存,但该内存中没有存储value。所以,我们在C中使用LS中定义的变量的话,只能取它的地址。下面是一个例子:

    start_of_ROM = .ROM;

    end_of_ROM = .ROM + sizeof (.ROM) - 1;

    start_of_FLASH = .FLASH;

    上面三个变量是在LS中定义的,分别指向.ROM段的开始和结尾,以及FLASH段的开始。现在在C代码中想把ROM段的内容拷贝到FLASH段中,下面是C代码:

    extern char start_of_ROM, end_of_ROM, start_of_FLASH;

    memcpy (& start_of_FLASH, & start_of_ROM, & end_of_ROM - & start_of_ROM);

    注意其中的取地址符号&。C代码中只能通过这种方式来使用LS中定义的变量. start_of_ROM这个值本身是没有意义的,只有它的地址才有意义。因为它的值没有初始化。

    地址就指向.ROM段的开头。

    说白了,LS中定义的变量其实就是地址,即_stext=0x100就是C代码中的一个地址 int *_stext=0x100。明白了?

    最终的ld中会分配一个slot,然后存储x的地址。也就是说,ld知道这些勾当。那么当然我们在LS中

    也可以定义一个变量,然后在C中使用了。所以下面这句话实际上定义了一个_stext变量。在C中通过extern就可以引用了。但是这里有一个

    比较关键的问题。C中定义的x=0,其值被初始化为0了。也就是slot...待补充

    */

    _stext = .;.

    _sinittext = .;

    *(.text.head)

    }

    //定义.init段,由所有的.init.text/.cpuinit.text/.meminit.text组成

    //这时的LC的值为.init的开始

    .init : { /* Init code and data        */

    *(.init.text) *(.cpuinit.text) *(.meminit.text)

    //定义一个变量 _einitext,它的值为当前的LC,即.init的初值+*(.init.text) *(.cpuinit.text) *(.meminit.text)的大小。也就是说变量

    //_einitext标示一个结尾。

    _einittext = .;

    //下面这个变量 __proc_info_begin标示一个开头

    __proc_info_begin = .;

    *(.proc.info.init)  //所有.proc.info.init段内容在这

    __proc_info_end = .;//下面这个变量 __proc_info_end标示结尾,它和__proc_info_begin变量牢牢得把输出文件.proc.info.init的内容卡住了。

    //有了上面begin和end的介绍,后面就简单了,大部分都是一个begin+end来卡住一段内容。根据前面的介绍,begin和end又可以在C程序中引用

    //也就是我们通过Begin+end,就可以获得卡住的内容了。例如我们把一些初始化的函数指针放到一个begin和end中。然后通过一个循环,不就是

    //可以调用这些函数了么。最后我们就来个例子介绍下。

    __arch_info_begin = .;

    *(.arch.info.init)

    __arch_info_end = .;

    __tagtable_begin = .;

    *(.taglist.init)

    __tagtable_end = .;

    . = ALIGN(16);

    __setup_start = .;

    *(.init.setup)

    __setup_end = .;

    __early_begin = .;

    *(.early_param.init)

    __early_end = .;

    __initcall_start = .;

    *(.initcallearly.init)

    __early_initcall_end = .;

    *(.initcall0.init) *(.initcall0s.init) *(.initcall1.init) *(.initcall1s.init) *(.initcall2.init) *(.initcall2s.init) *(.initcall3.init) *(.initcall3s.init) *(.initcall4.init) *(.initcall4s.init) *(.initcall5.init) *(.initcall5s.init) *(.initcallrootfs.init) *(.initcall6.init) *(.initcall6s.init) *(.initcall7.init) *(.initcall7s.init)

    __initcall_end = .;

    __con_initcall_start = .;

    *(.con_initcall.init)

    __con_initcall_end = .;

    __security_initcall_start = .;

    *(.security_initcall.init)

    __security_initcall_end = .;

    . = ALIGN(32);//ALIGN,表示对齐,即这里的Location Counter的位置必须按32对齐

    __initramfs_start = .;   //ramfs的位置

    usr/built-in.o(.init.ramfs)

    __initramfs_end = .;

    . = ALIGN(4096); //4K对齐

    __per_cpu_load = .;

    __per_cpu_start = .;

    *(.data.percpu.page_aligned)

    *(.data.percpu)

    *(.data.percpu.shared_aligned)

    __per_cpu_end = .;

    __init_begin = _stext;

    *(.init.data) *(.cpuinit.data) *(.cpuinit.rodata) *(.meminit.data) *(.meminit.rodata)

    . = ALIGN(4096);

    __init_end = .;

    }

    //DISACARD是一个特殊的section,表示符合这个条件的输入段都不会写到输出段中,也就是输出文件中不包含下列段

    /DISCARD/ : { /* Exit code and data        */

    *(.exit.text) *(.cpuexit.text) *(.memexit.text)

    *(.exit.data) *(.cpuexit.data) *(.cpuexit.rodata) *(.memexit.data) *(.memexit.rodata)

    *(.exitcall.exit)

    *(.ARM.exidx.exit.text)

    *(.ARM.extab.exit.text)

    }

    //省略部分内容

    //ADDR为内置函数,用来返回VMA的

    /*

    这里举个小例子,大家看看VMA和LMA到底有什么作用

    SECTIONS

    {

    .text 0x1000 : { *(.text) _etext = . ; }  /.text段的VMA为0x1000,而且LMA=VMA

    .mdata 0x2000 : //.mdata段的VMA为0x2000,但是它的LMA却在.text段的结尾

    AT ( ADDR (.text) + SIZEOF (.text) )

    { _data = . ; *(.data); _edata = . ; }

    .bss 0x3000 :

    { _bstart = . ; *(.bss) *(COMMON) ; _bend = . ;}

    }

    看到了么?.mdata段运行的时候在0x2000,但是数据load地址却在.text段后,所以运行的时候需要把.mdata段内容拷贝过去。

    extern char _etext, _data, _edata, _bstart, _bend;

    char *src = &_etext;  //_etext为.text端的末尾 VMA地址,但同时也是.mdata段LMA的开始,有LS种的AT指定

    char *dst = &_data;  //_data为mdata段的VMA,现在需要把LMA地址开始的内容拷贝到VMA开始的地方

    /* ROM has data at end of text; copy it. */

    while (dst < &_edata)

    *dst++ = *src++;   //拷贝....明白了?不明白的好好琢磨

    /* Zero bss. */

    for (dst = &_bstart; dst< &_bend; dst++)

    *dst = 0;  //初始化数据区域

    */

    .rodata : AT(ADDR(.rodata) - 0) {

    __start_rodata = .;

    *(.rodata) *(.rodata.*) *(__vermagic) *(__markers_strings) *(__tracepoints_strings)

    }

    .rodata1 : AT(ADDR(.rodata1) - 0) {

    *(.rodata1)

    }

    ......//省略部分内容

    _edata_loc = __data_loc + SIZEOF(.data);

    .bss : {

    __bss_start = .; /* BSS                */

    *(.bss)

    *(COMMON)

    _end = .;

    }

    /* Stabs debugging sections.    */

    .stab 0 : { *(.stab) }

    .stabstr 0 : { *(.stabstr) }

    .stab.excl 0 : { *(.stab.excl) }

    .stab.exclstr 0 : { *(.stab.exclstr) }

    .stab.index 0 : { *(.stab.index) }

    .stab.indexstr 0 : { *(.stab.indexstr) }

    .comment 0 : { *(.comment) }

    }

    //ASSERT是命令,如果第一个参数为0,则打印第二个参数的信息(也就是错误信息),然后ld命令退出。

    ASSERT((__proc_info_end - __proc_info_begin), "missing CPU support")

    ASSERT((__arch_info_end - __arch_info_begin), "no machine record defined")

    五  内核代码中使用LS中定义的变量

    咱们看一个小例子

    [-->init/main.c]

    extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[]; //这几个值在LS中定义。大家可以在上面搜索下

    static void __init do_initcalls(void)

    {

    initcall_t *call;

    //上面已经定义成数组了,所以下面这些变量直接取的就是指针,和上面例子中使用&一个意思,反正不能用value

    for (call = __early_initcall_end; call < __initcall_end; call++)

    do_one_initcall(*call);

    /* Make sure there is no pending stuff from the initcall sequence */

    flush_scheduled_work();

    }

    六 总结

    关于LS的详细文档,见下面的网址:

    上面文档写得比较粗,但大家知道两点即可:

    LK源码中那些找不到来源的变量是怎么来的---》在LS定义。

    VMA和LMA是怎么回事。

    【编辑推荐】

    【责任编辑:张叶青 TEL:(010)68476606】

    点赞 0

    展开全文
  • 作者:晓风轻链接:zhuanlan.zhihu.com/p/28615617近日里,很多人邀请我回答各种j2ee开发的初级问题,我无一都强调java初学者要先扎实自己的基础知识,那什么是java的基础知识?又怎么样才算掌握了java的基础知识...

    作者:晓风轻

    链接:zhuanlan.zhihu.com/p/28615617

    近日里,很多人邀请我回答各种j2ee开发的初级问题,我无一都强调java初学者要先扎实自己的基础知识,那什么才是java的基础知识?又怎么样才算掌握了java的基础知识呢?这个问题还真值得仔细思考。

    我做j2ee开发已经超过十载,作为过来人,心路历程估计和大家差不多。编码的前几年,很长一段时间觉得java简单,开发实现各种功能都很轻松,代码写起来根本不费劲(主要是因为写的代码都是一些功能业务逻辑)。但同时自己心里明白,自己其实没有什么水平,自己这3,4年以来学懂的东西就那么多,其他人几个月就可以学会,自己的竞争力在哪里?这种矛盾的心理,困扰了我非常长的时间,非常的苦恼!总有一种报国无门无处发力的感觉。

    这个时期,热衷了使用各种框架,各种api,常以今天学习了某个api,组件,框架的使用就觉得自己学到了东西,设计模式也看过不止一次,但都没有啥感觉。一方面很努力学习,一方面又觉得不踏实,因为例如这个api我知道而你不知道,但我告诉你之后你就知道了,那我比你的优势在哪里呢?苦恼*2

    过了很长一段这种惶惶不可终日的日子,决定自己要改变,改变的方向就是阅读自己用到的java相关的源代码,看看jdk是如何实现的。就从基本的数据结构看,然后看多线程相关,在学习前台等等。写的代码还是那些代码,代码还是那么简单,但我力求做到知道代码背后的真相,这就是我最开始努力的方向。于是不再把时间都花在追求各种新框架、新API的使用上,每天都花时间在看实现原理上。就这样过了大半年左右,终于不再迷茫,不会在觉得自己只懂api的使用,觉得自己没有那么肤浅了,说脱胎换骨也不为过。那段时间,是我成长最快的时期,也是最充实的一段时光。

     Talk is cheap,show me the code  举例说明大家会比较有感觉。

    如学习了hashmap的源代码知道了工作原理之后,使用hashmap

    MapString> map = new HashMap<>();

    代码还是那个代码,但我已经知道了hashmap背后的东西

    1. 数据结构是链表的数组(注:后面的版本为了提升性能,已经是改成链表或者树(节点较多)了)2. 思想上是空间换时间的算法3. 构造函数上有容量和负载因子2个参数以及作用4. 决定性能的是key的hashcode是否够快、结果够分散(不分散就会变成链表的性能了),和扩容的开销(什么时候扩容,和负载因子有关)然后写代码的时候,如果知道了最终的容量(尤其是数据量大的时候),我都会指定初始化容量,类似如下
    Listlist = doSomeThing();
    Mapmap = new HashMap<>((int)(list.size()/0.75));//0.75为默认负载因子
    如果工作中某个map使用特别多,性能还需要继续优化,我就会考虑从以下方面优化

    1. 如果key是自己定义的对象,那么hashcode方法是否够快(最少应该缓存保证只计算一次,而且放入之后不能改变,决定hashcode的字段不能改变)?hash的结果是否够分散?

    2. 可以考虑调小负载因子,花更多的空间来换时间

    学习源代码的时候,特别有意思,你会强烈感觉到一个词:举一反三!触类旁通!学习api使用的时候,如果你只知道使用不知道原理,很难举一反三,感觉的是死记硬背。但学习了原理之后,知识成体系后,很容易举一反三,学的越多就容易,还是以hashmap为例,我举一个hashmap反三个点。1. 你会知道但凡有数组的数据结构,构造函数都有一个容量的初始化参数(或者说构造函数有初始化容量的可能都是数组的数据结构)。构造函数如下
    public ArrayList(int initialCapacity) //LinkedList不是数组就没有public HashMap(int initialCapacity) public StringBuffer(int capacity)
    你就会知道,数组扩容很耗性能(数据量大容易oom),尽量指定容量。2. 算法是空间换时间,还有没有其他算法是这种思想的?你最少能找到一个桶排序。3. 数据库的分库分表,思路和hashmap大同小异4. 各种分布式的hash一致性算法,第一步都是创建一个最大的数组(Integer.MAX_VALUE),就是避免了hashmap最耗性能的扩容运算。学习了hashmap之后,你很自然就会去了解其他的map,如TreeMap,LinkedHashmap(超级有用),HashTable,ConcurrentSkipListMap(算法思路很有意思),ConcurrentHashMap等,你会知道set就是用map做的,都不需要学。到了这步,map相关就可以暂告一段落。在学习中,我发现思想上的东西是最重要的,你理解了思想,一下子就豁然开朗了,在也不需要死记硬背了。如学习CAS的时候,大家都知道这是一种指令级的免锁实现。看代码的时候,我一度疑惑为什么会有个while死循环(原谅我天资驽钝)
    public final int getAndUpdate(IntUnaryOperator updateFunction) {int prev, next;do {
                prev = get();
                next = updateFunction.applyAsInt(prev);
            } while (!compareAndSet(prev, next));return prev;
        }
    后来从思想上理解,才知道乐观锁的概念,就是很乐观,假设你不会出错,但你要是出错了我就重试有办法给你修复,对应的就是悲观锁,就是很悲观,觉得不锁就会出错,如synchronize关键字和reentrantlock。这体现了2种不同截然不同的管理思想。这种思想经常体现在多个系统集成的设计,有些时候如果你用悲观的思想设计,实现起来很麻烦或者无法实现,但如果你用乐观的思想,减少出错条件,然后出错了能解决,代价就会小很多。说了这么多,我想说的就是,j2ee的基础知识就是你做项目中代码背后的东西。提高自己水平的方法很简单,就是把大部分时间去了解实现原理,了解思想,让自己的知识串起来,形成体系。j2ee的知识特别多,学得人想哭,千万不要一开始把时间花在各种框架、组件的使用上,在我看来那是本末倒置。简单来说:先修内功再练招式。我觉得重要的、工作会用得到的知识就是一个请求从前台到后台处理的过程需要用到的东西,最少包括以下点:js,html,css,ajax,ajax跨域,跨站脚本,web缓存,web优化,nginx,apache作用,鉴权方式,cookie,session,servlet,filter,基本数据结构,线程池,线程并发,缓存,io等等,知识点非常多。如你前台用jq,你应该了解他的选择器和ajax是如何实现的(其实去了解就会发现不复杂)?而不是只是会用。后台你用springmvc,你要了解他是如何工作,每一个配置是做什么,为什么?

    j2ee知识点特别多,每一个都能写很多,我也在不断学习中。具体要写我还真不知道如何下手,我就列举一下我觉得基础的东西(面试的时候问的问题),有简单有难,你觉得偏可能是你没有做过这块的开发或者做得比较浅:

    1. map有哪些,特点和使用场景?(只知道hashmap,hashtable是不够的。)

    2. 哪些方面会影响hashmap的性能?

    3. 线程安全的map有哪些,concurrenthashmap是如何实现线程安全的(jdk1.8大不同)?

    4. 锁有哪几种?

    5. 公平锁,读写锁等如何实现?

    6. synchronize能加在哪些地方?什么区别?

    7. 死锁的形成条件?现在很少死锁了,很少问

    8. 原子数据对象的原理?

    9. reentrantlock相关知识,condition如何使用?(很重要的知识点,强烈推荐阅读ArrayBlockingQueue源码,教科书般)

    10. volatile的相关知识(内存屏障,重排)

    11. ThreadLocal原理和使用?(超级有用的知识点,工作中使用很多,让代码漂亮很多,后面专门开贴写)

    12. 多个线程同步等待?(CountDownLatch,CyclicBarrier,Semaphore信号量很多语言都有,实际上使用不是很多,线程池就可以实现大部分等待功能)

    13. 线程池?(种类,重要的方法,这个一般是使用层面,简单)

    14. 动态代理?反射?内省?(考察知识面)

    15. session相关知识?和cookie关系?分布式session实现原理?

    16 cookie相关知识?有哪些属性?(有些属性很有用,只是我们很少留意而已!)

    17. nginx,apache 实际项目能做哪些?(鉴权,转发,缓存,反向代理等)和tomcat什么关系?最少了解

    18 ajax跨域原因?解决方式?(重点知识,做SE避免不了的问题。这里很多知识点。)

    19 jsonp原理?后台需要改动吗?(jsonp虽然现在落伍了,但还是会问问)

    20. web优化知识点?(常规知识点)

    21. 前台缓存相关?(200cache,304,ajax缓存,如何实现缓存)

    一列举就根本停不下来了。。。其他的spring框架的东西也很多,还有jvm的东西,系统集成相关,数据库相关,io做得很少也不懂问,后面再慢慢把我的学习过程和偶得写下来。很多东西我也是了解个大概,就是看看你有没有学习过,不断学习是程序员最重要的特征。我不算高手,只能算一个合格的老程序员。这里只是说了一下自己之前学习的方向和列举了几个学习中的例子,大家见仁见智。帖子也是针对迷茫的初学者有感而发,希望能帮助到大家。最后我总结一下:初学者先广在精,关注代码背后的实现,关注内功修炼,了解实现原理和思想,形成自己完整的技术体系,知识成片之后就容易触类旁通,进步的速度就会越来越快。最后以我在每一个项目组和开发人员聊天都会说的几个例子结尾:“少林功夫里面有功和拳之分,马步功,石锁功是功,蛇拳猴拳是拳,你不可能练会了蛇拳猴拳就能打人,你必须先重点练功。乔峰在聚贤庄用太祖长拳把大家打得落花流水,我们用太祖长拳就只是个广播体操。同样,我们要分清编程里面那些是功那些是拳,代码背后的实现和思想是功,各个框架、api使用是拳。初学者应该大部分时间花在练功上,功到了拳自然就有了,切勿本末倒置。”谢谢大家阅读!开了一个专栏,记录作者的学习之路和编程习惯,每周最少一更,欢迎关注本文作者的专栏:https://zhuanlan.zhihu.com/c_120823325本文作者,晓风轻,知乎链接:https://zhuanlan.zhihu.com/c_120823325。
    -END-1.  Spring 中运用的 9 种设计模式吗 ?2. Java 中的继承和多态(深入版)3. 如何降低程序员的工资?4. 编写 Spring MVC 的 14 个小技巧

    9defb26ced00c3476981d45413145aec.png在看 422be780fcec2f8fbada3feec2016590.png

    展开全文
  • 在第一部分,我讲解了RxJava的基本结构,也介绍了map()操作。然而,我能理解你仍旧不会选择使用Rxjava——你仍然还有...初始假设我有一个这样的方法://返回一个基于文本查询网站链接的列表Observable> query(Str...
  • Java 中的Monitor是什么意思

    千次阅读 2017-03-16 20:56:56
    详情参见如下链接: https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
  • JAVA学习-JDK下载与安装JDK是什么下载1.点开链接后,如下图选择下载,最好是jdk1.8,下载需要登陆,所以还需要创建一个Oracle账号,不过很简单:2.你需要根据你的电脑系统来进行对应的版本选择(我的是Windows x64)...
  • 根据JEP我链接的评论(也here),A caller-sensitive method varies its behavior according to the classof its immediate caller. It discovers its caller’s class by invokingthe sun.reflect.Reflection....
  • 参考链接Java中的Super关键字 this和super关键字 this自身的一个对象,代表对象本身可以理解为指代当前的对象,它可以调用当前对象的属性、方法和构造方法,一般情况下可以省略,必须使用this的地方区分...
  • 由于2003的操作系统在提示IIS过多时并非像32313133353236313431303231363533e4b893e5b19e313333656661392000系统提示“链接人数过多”,而是提示"Service Unavailable",出现这种情况由于网站超过了系统资源限制...
  • 1、用户误操作不小心将程序安装目录中的e68a8462616964757a686964616f31333366306464动态链接库DLL文件删除,导致程序启动时无法找到必要的文件而报错(这种情况并不是普遍存在的,但也原因之一)。2、电脑感染木马...
  • 点击上方“java进阶架构师”,选择右上角“置顶公众号”20大进阶架构专题每日送达Java并发编程脑图本文为何适原创并发编程系列第 10 篇,前面几篇没看过的,可以在文末找到前几篇的跳转链接。前面几篇理论知识介绍了...
  • 部分面试资料链接:...java 中 hashCode() 和 equals() 的关系面试中的常考点,如果没有深入思考过两者设计的初衷,这个问题将很难回答。除了应付面试,理解二者的关系更有助于我们写出高质量且准确的代码。...
  • 这可能最容易解释的负面例子,如在其他答案的链接文章。 unpythonic代码的例子通常来自其他语言的用户,而不是学习Python编程模式(如列表推导或生成器表达式),而是尝试在C或java中更常用的模式中使用撬杠。循环...
  • java中都值传递,完整的意思是java中按值传递传递的值的拷贝,按引用传递其实传递的引用的地址值,所以统称按值传递。 其实大家纠结java到底值传递还是引用传递,主要以下四种场景造成的: (例子...
  • 链接css或js文件时后面带有问号参数是什么意思? <link href="/stylesheets/display.css?1166154827 " media="screen" rel="Stylesheet" type="text/css" />  <script src="/java scripts/...
  • 1、背景最近在负责公司基础业务和移动基础设施的开发工作,正在负责Lint代码静态检查工作。因此编写了自定义的Lint规则... google官方的lint源代码链接为: https://android.googlesource.com/platform/tools/base/+/
  • 从字面上的意思理解,应该就是Java全栈技术学习路线图。当然这种路线图现在网络上很多,但是我不建议你按路线图走。因为你既然问这个我那天,那么说明你可以对Java的了解可能零基础。所以建议你还是先从基础学期。...
  • 程序写好了,同时包也导入了,为什么连接不上呢,还有这些错误是什么意思啊?会不会是包导错了呢?求帮助![图片说明](https://img-ask.csdn.net/upload/201711/19/1511084812_923581.png)![图片说明]...
  • 是什么意思? 这有什么用途?#1楼通常创建无序列表是为了将它们用作菜单,但是li列表项是文本。 因为列表li的项目是文本,鼠标指针会不会是一个箭头,而是一个“I形光标”。 用户习惯于单击某些东西时看到指向...
  • 原文链接:点击打开链接 ...不能改变状态的意思是,不能改变对象内的成员变量,包括基本数据类型的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变。 区分对象和对象的引用 ...
  • 这里是修真院后端小课堂,每篇分享文从 【背景介绍】【知识剖析】...【 Spring中的IOC是什么意思,为什么要用IOC而不是New来创建实例?】 PPT链接:https://ptteng.github.io/PPT/PPT-java/java_task1_14_Spr...
  • 1、背景 最近在负责公司基础业务和移动基础设施的开发工作,正在负责Lint代码静态检查工作。因此编写了自定义的Lint规则,在编写自定义的Lint规则前,当然需要... google官方的lint源代码链接为: https://andr...
  • @Override是Java5的元数据,自动加上去的一个标志,告诉你说下面这个方法从父类/接口 继承过来的,需要你重写一次,这样就可以方便你阅读,也不怕会忘记 @Override伪代码,表示重写(当然不写也可以),不过写上有...
  • sql = new String(sql.getBytes(),"gb2312"); 请问这句话的具体意思是什么
  • 友情链接是什么意思友情链接就是两个网站互相交互链接,互相导入导出权重,这样的话,对双方网站的权重排名都有好的影响,友情链接是最重要的外链获取方式之一。但是,如果一方网站出了问题,比如网站被黑,跟这个...
  • 一文弄懂Java和C中动态链接机制

    千次阅读 2019-01-31 03:08:59
    概念为了做实际的对比,先把概念搞清楚...那么再进一步,链接是什么意思?模块、符号和链接大多数日常使用的都是高级语言。为了方便管理和关注点分离(Separation of Concern),一个具备一定规模的程序通常会拆分...
  • 开发Java程序时,我们想编辑一个 .java文件,然后该文件被编译器编译成 .class文件。Java在运行时,自己加载...1、 “加载一个类”是什么意思?在C/C++中,首先被编译成本地机器代码,然后在编译之后有一个链接过程...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 182
精华内容 72
关键字:

java链接是什么意思

java 订阅