if v.IsNil() {
                        v.Set(reflect.New(v.Type().Elem()))
                }
-               if v.Type().NumMethod() > 0 {
+               if v.Type().NumMethod() > 0 && v.CanInterface() {
                        if u, ok := v.Interface().(Unmarshaler); ok {
                                return u, nil, reflect.Value{}
                        }
 
        Z interface{}
 }
 
+type unexportedWithMethods struct{}
+
+func (unexportedWithMethods) F() {}
+
 func sliceAddr(x []int) *[]int                 { return &x }
 func mapAddr(x map[string]int) *map[string]int { return &x }
 
 //
 // (Issue 24152) If the embedded struct is given an explicit name,
 // ensure that the normal unmarshal logic does not panic in reflect.
+//
+// (Issue 28145) If the embedded struct is given an explicit name and has
+// exported methods, don't cause a panic trying to get its value.
 func TestUnmarshalEmbeddedUnexported(t *testing.T) {
        type (
                embed1 struct{ Q int }
                        embed2 `json:"embed2"`
                        Q      int
                }
+               S9 struct {
+                       unexportedWithMethods `json:"embed"`
+               }
        )
 
        tests := []struct {
                in:  `{"embed1": {"Q": 1}, "embed2": {"Q": 2}, "Q": 3}`,
                ptr: new(S8),
                out: &S8{embed1{1}, embed2{2}, 3},
+       }, {
+               // Issue 228145, similar to the cases above.
+               in:  `{"embed": {}}`,
+               ptr: new(S9),
+               out: &S9{},
        }}
 
        for i, tt := range tests {