1
00:00:02,039 --> 00:00:07,013
In this video, we're going to wrap up our
discussion of Java by taking a look at a

2
00:00:07,013 --> 00:00:11,082
couple of additional topics and how they
are integrated into the language design.

3
00:00:13,035 --> 00:00:18,097
Consistent with Java's dynamic nature Java
allows classes to be loaded at runtime.

4
00:00:19,190 --> 00:00:24,071
But this means that you can actually add
functionality to an executing Java program

5
00:00:24,071 --> 00:00:29,086
so, while it's running, by loading a new
class. And this creates potential issues

6
00:00:29,086 --> 00:00:35,061
with type safety and security because now
there is a distinction between compiled

7
00:00:35,061 --> 00:00:40,401
time and load time. So, type checking of
the source takes place at compile time and

8
00:00:40,401 --> 00:00:46,420
this is the kind of type checking we
discussed in earlier in earlier videos.

9
00:00:46,420 --> 00:00:50,959
But the, the loader, when you actually go
to load a class, you're loading bytecode,

10
00:00:50,959 --> 00:00:55,657
you're not loading source and it's not
being type checked again. And it could be,

11
00:00:55,657 --> 00:01:00,770
that this bytecode didn't come, you know,
from a trusted source. This bytecode might

12
00:01:00,770 --> 00:01:04,997
not be the output of a compiler that did
type checking, before it produced the

13
00:01:04,997 --> 00:01:09,698
bytecode. So, the bytecode might not
actually satisfy the type assumptions of

14
00:01:09,698 --> 00:01:14,586
the Java implementation. So essentially,
we have to check the bytecode again. And

15
00:01:14,586 --> 00:01:18,989
a, and a procedure called bytecode
verification takes place when the class is

16
00:01:18,989 --> 00:01:23,964
loaded, alright. And, and byte code
verification is really a type checking of

17
00:01:23,964 --> 00:01:29,310
bytecode. That's, that's essentially what
it does. The procedure is a little bit

18
00:01:29,310 --> 00:01:35,100
different because we don't have you know,
the code here is much lower level and so

19
00:01:35,100 --> 00:01:39,609
the algorithms look a little bit
different. But what they're really doing

20
00:01:39,609 --> 00:01:44,072
is type checking the, thebytecode. So, now
the loading policies are handled by

21
00:01:44,072 --> 00:01:49,087
something called the class loader. And the
class loader is a special class in Java

22
00:01:49,087 --> 00:01:53,970
and it decides what classes can be loaded
and actually early on in Java, a bunch of

23
00:01:53,970 --> 00:01:59,143
security problems were discovered. Aware
an attacker could get control of the class

24
00:01:59,143 --> 00:02:04,299
loader install it's own class loader that
would be much more permissive than the

25
00:02:04,299 --> 00:02:09,139
Java standard class loader and subve rt
the system. But those issues were fixed

26
00:02:09,322 --> 00:02:14,084
quite awhile ago, alright. And another
interesting thing about Java is that the

27
00:02:14,084 --> 00:02:18,371
classes may also be unloaded. So, you
don't, you can not, not only load classes,

28
00:02:18,371 --> 00:02:23,559
you can also unload classes. And the last
time I checked this was not particularly

29
00:02:23,559 --> 00:02:28,108
well specified in the definition and so
it's a little bit unclear exactly what it

30
00:02:28,108 --> 00:02:32,531
meant when you unloaded the class and what
happened to all the existing objects, for

31
00:02:32,531 --> 00:02:37,696
example, of that class. Now, I'd like to
spend a few minutes talking about

32
00:02:37,696 --> 00:02:43,304
initialization in Java, which is quite
complex, and this shouldn't be too much of

33
00:02:43,304 --> 00:02:48,605
a surprise because if you remember
initialization in COOL was also pretty

34
00:02:48,605 --> 00:02:53,733
complex and Java is just a superset of
COOL so it has all the initialization

35
00:02:53,733 --> 00:02:59,549
issues that COOL has plus much more. And
now the main source of complication is

36
00:02:59,549 --> 00:03:04,929
concurrency but other language features
also add to the complexity of

37
00:03:04,929 --> 00:03:12,813
initialization in Java. And, in fact you
could do worse. If you want to understand

38
00:03:12,813 --> 00:03:19,495
a new object oriented language, then study
how it does object initialization and

39
00:03:19,495 --> 00:03:25,044
class initialization. Because essentially
what happens in initialization is that all

40
00:03:25,044 --> 00:03:30,899
the features of the language are going to
be interacting and you have to explain

41
00:03:30,899 --> 00:03:36,189
what all those interactions are and how
they are sorted out in order to have a

42
00:03:36,189 --> 00:03:41,677
well-defined initialization procedure,
alright. So, now let's talk about class

43
00:03:41,677 --> 00:03:47,141
initialization. We won't talk about object
initialization, we'll just talk about

44
00:03:47,141 --> 00:03:51,992
initializing classes. So, this is how the,
the object that represents a class

45
00:03:52,184 --> 00:03:58,329
actually gets initialized when that class
is first brought into the program. And so,

46
00:03:58,329 --> 00:04:04,073
the first thing to know is that a class is
initialized when a symbol in a class is

47
00:04:04,073 --> 00:04:09,089
first used, okay, not when the class is
loaded, alright? So, if you reference any

48
00:04:09,089 --> 00:04:15,001
symbol in the class at the first time that
happens that will cause the class to be

49
00:04:15,001 --> 00:04:19,081
initialized. And the reason for doing this
is if you are going to have an error in

50
00:04:19,081 --> 00:04:23,512
class initialization, th is will cause
that error to happen in a predictable

51
00:04:23,512 --> 00:04:28,064
place. So, if you have an error and you
run the, you, you have an error in class

52
00:04:28,064 --> 00:04:32,588
initialization if you run the program five
times you know, that error will probably

53
00:04:32,588 --> 00:04:37,185
happen in the same place every time. So,
it'll be repeatable and predictable where

54
00:04:37,185 --> 00:04:42,060
the error occurs. If instead we had, the
error happened where you loaded the class

55
00:04:42,060 --> 00:04:46,243
at the time that you loaded the class,
well, the class might be loaded at lots of

56
00:04:46,243 --> 00:04:52,222
different times. And, and, and so this,
this, this error here the error in the

57
00:04:52,222 --> 00:04:58,272
initialization of the class would become
non-deterministic if we didn't if we

58
00:04:58,272 --> 00:05:04,306
didn't delay the initialization until some
deterministic point in the execution. So,

59
00:05:04,306 --> 00:05:09,881
now I'll discuss the procedure for
initializing class objects in Java. And

60
00:05:09,881 --> 00:05:15,632
the first thing I should stress is that
this idea of a class object is something

61
00:05:15,632 --> 00:05:20,764
that Java has that COOL does not have, I
mentioned this on the previous slide. But

62
00:05:20,764 --> 00:05:26,305
just to be completely clear, what is a
class object? A class object is just what

63
00:05:26,305 --> 00:05:32,228
it sounds like, it is the object for a
class. It represents a class. Okay, this

64
00:05:32,228 --> 00:05:37,760
is not an instance of the class. This is
an object which is the class, okay. So,

65
00:05:37,760 --> 00:05:42,819
this is an object which is the class, it
has all the information about the class

66
00:05:42,819 --> 00:05:47,798
so, you know, it tells you what the type
of the class is, what the fields of the

67
00:05:47,798 --> 00:05:52,769
class are, and everything else. So, this
is used for introspection or reflection.

68
00:05:52,769 --> 00:05:57,503
And it's necessary in Java because of
features like dynamic loading. So, if, you

69
00:05:57,503 --> 00:06:02,117
know, if you want, if you dynamically load
a class though you want to be able to use

70
00:06:02,117 --> 00:06:07,065
that class, you have to have some way of
querying what the, what kinds of methods

71
00:06:07,065 --> 00:06:11,993
and things the class has and that is what
the class object is for. So, there is one

72
00:06:11,993 --> 00:06:16,844
object, there is one class object for each
class in Java, alright. So, when you load

73
00:06:16,844 --> 00:06:21,590
a class, the first thing you have do is to
initialize the class object. And how is

74
00:06:21,590 --> 00:06:25,989
that done? Well, we lock the class object
for the class, alright. And if th at, if

75
00:06:25,989 --> 00:06:32,597
that object is already locked by another
thread, then we'll simply wait on the

76
00:06:32,597 --> 00:06:38,074
lock, okay. So, we will wait until
somebody tells us that it's okay to

77
00:06:38,074 --> 00:06:45,037
proceed. Now once we obtain the lock on
the class, we have to do a check to see if

78
00:06:45,037 --> 00:06:51,284
the class is already being initialized,
alright. So, and it could turn out that it

79
00:06:51,284 --> 00:06:57,082
is our thread, it is the same thread is
already initializing the class. And how

80
00:06:57,082 --> 00:07:04,096
could that happen? Well, remember that a
class can have fields of the same type.

81
00:07:04,096 --> 00:07:11,204
So, I could have a class of class called X
and then it could have a field of type X

82
00:07:11,204 --> 00:07:16,033
in it. And the way classes are going to be
initialize if we're going to have to

83
00:07:16,033 --> 00:07:20,021
initialize the class itself and then, and
we're going to do that by recursively

84
00:07:20,021 --> 00:07:24,015
initializing the classes for all the
fields or at least making sure of the

85
00:07:24,015 --> 00:07:28,056
classes for all the fields are initialize.
And if we have a recursive structure here

86
00:07:28,056 --> 00:07:32,687
with the same class mention in a field as
in a name, as the name of the enclosing

87
00:07:32,687 --> 00:07:36,468
class, then we will get the situation
where the thread initializing the class

88
00:07:36,468 --> 00:07:40,589
may attempt to initialize the same class
again. So, if we discover that we're

89
00:07:40,589 --> 00:07:45,028
already initializing this class, we simply
release the lock and we turn. Now, another

90
00:07:45,028 --> 00:07:48,886
possibility is that the class is already
initialized. So, if when we finally get

91
00:07:48,886 --> 00:07:53,655
the lock we discover that some other
thread got in there and initialized the

92
00:07:53,655 --> 00:07:57,669
class before we have a chance to., well,
then there's nothing to do and we just

93
00:07:57,669 --> 00:08:01,663
return normally, alright? Now, if neither
one of these things is true, okay, if we

94
00:08:01,663 --> 00:08:07,330
get the lock and we discover that the
class is not already initialized and that

95
00:08:07,330 --> 00:08:12,482
we're not already in the process of
initializing the class, then we will mark

96
00:08:12,482 --> 00:08:17,101
the class to, to note the initialization
is in progress by this thread, okay. So,

97
00:08:17,101 --> 00:08:21,134
we'll indicate, you know, this class is
being initialized and that we are

98
00:08:21,134 --> 00:08:26,746
initializing it and then we'll unlock the
class. Alright, the next thing that

99
00:08:26,746 --> 00:08:31,595
happens is we'll have to initialize the
superclass and that will m ean initial,

100
00:08:31,595 --> 00:08:36,771
and then we'll initialize all the fields
in textual order. But because Java has

101
00:08:36,771 --> 00:08:41,998
what are called static and final fields we
will initialize those first, okay. So,

102
00:08:41,998 --> 00:08:47,183
static final fields will get initialized
before any other fields in textual order.

103
00:08:47,183 --> 00:08:51,519
And, of course, we have to give every
field of default value before

104
00:08:51,519 --> 00:08:56,306
initialization just as in COOL. So, this
step, step five is very similar to what

105
00:08:56,306 --> 00:09:02,362
goes on in COOL. Now if there's an error
during the initialization, so some part of

106
00:09:02,362 --> 00:09:06,837
the initialization throws an exception,
then we're going to mark the class as

107
00:09:06,837 --> 00:09:11,637
erroneous, okay, we're going to mark this
class as no good and can't be used and,

108
00:09:11,637 --> 00:09:15,675
and that's the best we can do. So, if
there's an exception during

109
00:09:15,675 --> 00:09:20,686
initialization, we just have to give up on
that class. And so it gets a special mark

110
00:09:20,686 --> 00:09:25,623
on it saying that it's erroneous. And, if
there are no errors if we succeed in

111
00:09:25,623 --> 00:09:30,017
initializing the class and with and
without any errors, then we're going to

112
00:09:30,163 --> 00:09:34,133
lock the class again. We will label the
class as initialized, alright? And then

113
00:09:34,133 --> 00:09:39,016
we'll notify the threads that are waiting
on the class object. So. Anybody who was

114
00:09:39,016 --> 00:09:43,881
locked waiting on the class object will
now be alerted that the object is, is

115
00:09:43,881 --> 00:09:49,002
ready and then we'll unlock the class.
Okay, and so that's a rough outline of how

116
00:09:49,002 --> 00:09:53,265
class initialization in Java works. I
skipped over a few things and

117
00:09:53,265 --> 00:09:58,182
oversimplified it a bit. So, this isn't
the complete description but these are the

118
00:09:58,182 --> 00:10:01,860
main points and they, and they illustrate
how the various features of the language

119
00:10:01,860 --> 00:10:06,048
have to interact. So, you have to worry
about concurrency, you have to worry about

120
00:10:06,048 --> 00:10:10,070
exceptions, you have to worry about static
and final fields, you have to worry about

121
00:10:10,070 --> 00:10:14,098
inheritance. I mean, all these things have
to be dealt with together in the design of

122
00:10:14,098 --> 00:10:18,850
a single algorithm to do class
initialization. Stepping back for a moment

123
00:10:19,062 --> 00:10:24,012
this discussion of class initialization in
Java illustrates a general point about

124
00:10:24,012 --> 00:10:28,034
designing complex systems. So, in any
system with a certain number of featu res

125
00:10:28,035 --> 00:10:32,041
and every system is going to have some
number of features, let's call it N,

126
00:10:32,041 --> 00:10:36,020
because you want to provide some
functionality, obviously the thing the

127
00:10:36,020 --> 00:10:40,059
system's suppose to d so its going to have
features to do those things. But as you

128
00:10:40,059 --> 00:10:43,493
add features, you get lots of
interactions, potential interactions

129
00:10:43,493 --> 00:10:47,502
between the features and if we think
about, even just the pairwise

130
00:10:47,502 --> 00:10:52,611
interactions. If I have N features, then
I'll have, I don't know, about N^2

131
00:10:52,611 --> 00:10:57,993
pairwise feature interactions. And the
point there, of course, is that as I add

132
00:10:57,993 --> 00:11:02,080
features the number of possible
interactions grows super linearly in the

133
00:11:02,080 --> 00:11:06,633
number of features, I mean, it grows much
more quickly than the number of features.

134
00:11:06,633 --> 00:11:10,869
And so, adding the next feature, you're
going to have to consider all of the

135
00:11:10,869 --> 00:11:14,937
previous features that you already have in
the system and how this new feature

136
00:11:14,937 --> 00:11:19,678
affects them, and this is why it becomes
very difficult to extend or build systems

137
00:11:19,678 --> 00:11:24,214
that have a lot of features, alright. And
this is just the pairwise features. These

138
00:11:24,214 --> 00:11:28,584
are just, this is just considering
pairwise interactions between one feature

139
00:11:28,584 --> 00:11:32,940
and another. If I have to start worrying
about subsets of features, I'm thinking

140
00:11:32,940 --> 00:11:37,539
about how all possible subsets of features
might interact with each other, well then,

141
00:11:37,539 --> 00:11:42,160
this step, this number of, of potential
interactions will grow not just it will

142
00:11:42,160 --> 00:11:46,618
grow, in fact, exponentially. So, it'd be,
you know, way more than quadratic. And the

143
00:11:46,618 --> 00:11:51,551
bottom line here is that big, feature-full
systems are hard to understand. You know,

144
00:11:51,551 --> 00:11:56,288
this is you know, a general lesson in
Computer Science and any kind of

145
00:11:56,288 --> 00:12:00,970
discipline that wants to design complex
systems and, and this lesson applies to

146
00:12:00,970 --> 00:12:05,555
programming languages. It applies to every
other kind of software system that you

147
00:12:05,555 --> 00:12:09,972
might want to build. But, and somehow it
has a particular force in programming

148
00:12:09,972 --> 00:12:14,601
languages because these interactions
between the features, you know, these are

149
00:12:14,601 --> 00:12:19,639
the features of the programming language,
they happen at a very fine grain. And

150
00:12:19,639 --> 00:12:24,586
these things can be, really can b e
composed arbitrarily and so you really do

151
00:12:24,586 --> 00:12:29,523
have to work out in language design, you
know, what all the interactions are in

152
00:12:29,523 --> 00:12:34,460
order to have a language that people, that
programmers can actually understand and

153
00:12:34,460 --> 00:12:40,665
use productively. Alright? And that really
I think is the big, big idea that, one of

154
00:12:40,665 --> 00:12:45,391
the big ideas that we've talked about
throughout the course. And, and I hope one

155
00:12:45,391 --> 00:12:51,094
of the things that you would take away
from this lecture at least in particular.

156
00:12:51,094 --> 00:12:56,432
So, to summarize and to conclude our
discussion of Java, I think Java is a, is

157
00:12:56,432 --> 00:13:00,483
a well-done language. By production
standards, it is extremely well-done. So,

158
00:13:00,483 --> 00:13:05,273
it's one of the best designed and best
specified languages that's in, in use

159
00:13:05,273 --> 00:13:10,892
today. It brought several important ideas
into the main stream. So, when it was new

160
00:13:11,225 --> 00:13:16,224
it brought ideas that had been around for
a long time but had not found their way

161
00:13:16,224 --> 00:13:22,025
into a production language that was very,
very widely used and in particular, Java

162
00:13:22,025 --> 00:13:27,133
was the first language to be very widely
used in, in commercial settings. They had

163
00:13:27,133 --> 00:13:32,380
strong sets of typing there that had real
guarantees they were, you know, provided

164
00:13:32,380 --> 00:13:37,913
by the type-system and also there was a
manage language and had a garbage

165
00:13:37,913 --> 00:13:42,615
collected memory. But that doesn't mean
it's perfect. And it, and Java also

166
00:13:42,615 --> 00:13:47,657
includes some features that, at the time
that it was designed, that we didn't fully

167
00:13:47,657 --> 00:13:51,825
understand and I would say, you know, that
this are probably the rough areas where

168
00:13:51,825 --> 00:13:56,772
there's still some roughness in the, in,
in the Java design. So, things like the

169
00:13:56,772 --> 00:14:01,044
way the memory semantics work in the
presence of concurrency, you know,

170
00:14:01,044 --> 00:14:04,999
probably still has most people would agree
I think, you now, has some problems and

171
00:14:04,999 --> 00:14:09,692
some, some little gray areas that as a
program, you probably want to stay out of.

172
00:14:09,692 --> 00:14:15,561
And the other thing is that Java has a lot
of features. And as I said before when you

173
00:14:15,561 --> 00:14:21,277
have a lot of features, you're going to
have even more feature interactions and

174
00:14:21,277 --> 00:14:25,089
that leads to complexity that becomes
difficult to manage.
