I assume the four requirements, of which at three must be met, are as follows. The string must contain:
- a letter
- a digit
- a character in the string "!@#$%^&*"
- at least 8 characters
Is the use of a regular expression the best way to determine if a password meets three of the four requirements? That may be a valid question but it's not the one being asked or the one that I will attempt to answer. The OP may just be curious: can this problem be solved using a regular expression? Moreover, even if there are better ways to address the problem there is educational value in answers to the specific question that's been posed.
I am not familiar with Java, but I can suggest a regular expression that uses Ruby syntax. Readers unfamiliar with Ruby should be able to understand the expression, and its translation to Java should be straightforward. (If a reader can perform that translation, I would be grateful to see an edit to this answer that provides the Java equivalent at the end.)
r = /
    ((?=.*[a-z]))      # match a lowercase letter in the string in
                       # a positive lookahead in cap grp 1, 0 times
    ((?=.*\d))         # match a digit in the string in a positive
                       # lookahead in cap grp 2, 0 times
    ((?=.*[!@#$%^&*])) # match a special character in in the string
                       # in a positive lookahead in cap grp 3, 0 times
    (.{8,})            # match at least 8 characters in cap grp 4, 0 times
    \g<1>\g<2>\g<3>    # match conditions 1, 2 and 3
    |                  # or
    \g<1>\g<2>\g<4>    # match conditions 1, 2 and 4
    |                  # or
    \g<1>\g<3>\g<4>    # match conditions 1, 3 and 4
    |                  # or
    \g<2>\g<3>\g<4>    # match conditions 2, 3 and 4
    /xi                # case indiff & free-spacing regex def modes 
\g{2}, for example, is replaced by the sub-expression contained in capture group 2 ((?=.*\d)). The first four lines each contain an expression in a capture group, with the capture group repeated zero times. This is just a device to define the subexpressions in the capture groups for retrieval later.
Let's test some strings.
"Passw0rd".match? r  #=> true  (a letter, digit and >= 8)
"ab2c#45d".match? r  #=> true  (all 4 conditions satisfied)
"ab2c#5d".match?  r  #=> true  (a letter, digit and special char)
"ab2c345d".match? r  #=> true  (a letter, digit and >= 8)
"ab#c?def".match? r  #=> true  (a letter, special char and >= 8)
"21#6?512".match? r  #=> true  (a digit, special char and >= 8)
"ab26c4".match?   r  #=> false (only letter and digit)
"a$b#c".match?    r  #=> false (only letter and special char)
"abc ef h".match? r  #=> false (only letter and >= 8)
"12 45 78".match? r  #=> false (only digit and >=8)
"########".match? r  #=> false (only special char and >= 8)
"".match          r  #=> false (no condition matched) 
To use named capture groups, ((?=.*[a-z])) would be replaced with, say,
(?<letter>(?=.*[a-z]))
and \g<1>\g<2>\g<3> would be replaced by something like
\g<letter>\g<digit>\g<spec_char>